diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2015-10-21 03:46:28 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2015-10-21 03:46:28 +0000 |
| commit | 9ccee73baca0fd7ecb95c90cb983133b737c6c55 (patch) | |
| tree | 66fea1e6521df31727431520fe3c1ead1896bc5d /Graphics | |
| download | DiligentCore-9ccee73baca0fd7ecb95c90cb983133b737c6c55.tar.gz DiligentCore-9ccee73baca0fd7ecb95c90cb983133b737c6c55.zip | |
Release v1.0.0
Diffstat (limited to 'Graphics')
246 files changed, 39640 insertions, 0 deletions
diff --git a/Graphics/GraphicsEngine/build/Windows/Android/gcc_Debug.h b/Graphics/GraphicsEngine/build/Windows/Android/gcc_Debug.h new file mode 100644 index 00000000..da574716 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/Android/gcc_Debug.h @@ -0,0 +1,249 @@ +/* + This file is only used by IntelliSense (VisualStudio code suggestion system) + DO NOT INCLUDE THIS FILE FROM YOUR ACTUAL SOURCE FILES. + This file lists the preprocessor macros extracted from your GCC. + It is needed for IntelliSense to parse other header files correctly. +*/ +#ifdef _MSC_VER +#define __DBL_MIN_EXP__ (-1021) +#define __UINT_LEAST16_MAX__ 65535 +#define __FLT_MIN__ 1.1754943508222875e-38F +#define __UINT_LEAST8_TYPE__ unsigned char +#define __CHAR_BIT__ 8 +#define __UINT8_MAX__ 255 +#define __ANDROID__ 1 +#define __WINT_MAX__ 4294967295U +#define R3000 1 +#define __ORDER_LITTLE_ENDIAN__ 1234 +#define __SIZE_MAX__ 4294967295U +#define __WCHAR_MAX__ 2147483647 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +#define __DBL_DENORM_MIN__ double(4.9406564584124654e-324L) +#define __FLT_EVAL_METHOD__ 0 +#define __unix__ 1 +#define _MIPS_ISA _MIPS_ISA_MIPS32 +#define __UINT_FAST64_MAX__ 18446744073709551615ULL +#define __SIG_ATOMIC_TYPE__ int +#define __DBL_MIN_10_EXP__ (-307) +#define __FINITE_MATH_ONLY__ 0 +#define _MIPS_TUNE "mips32" +#define _ABIO32 1 +#define __GNUC_PATCHLEVEL__ 0 +#define __UINT_FAST8_MAX__ 255 +#define __DEC64_MAX_EXP__ 385 +#define __UINT_LEAST64_MAX__ 18446744073709551615ULL +#define __SHRT_MAX__ 32767 +#define __LDBL_MAX__ 1.7976931348623157e+308L +#define __UINT_LEAST8_MAX__ 255 +#define __mips_abicalls 1 +#define __UINTMAX_TYPE__ long long unsigned int +#define __linux 1 +#define __DEC32_EPSILON__ 1E-6DF +#define __unix 1 +#define __UINT32_MAX__ 4294967295U +#define __LDBL_MAX_EXP__ 1024 +#define __LANGUAGE_C_PLUS_PLUS 1 +#define __WINT_MIN__ 0U +#define __MIPSEL__ 1 +#define __linux__ 1 +#define __SCHAR_MAX__ 127 +#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) +#define __DBL_DIG__ 15 +#define __SIZEOF_INT__ 4 +#define __SIZEOF_POINTER__ 4 +#define __USER_LABEL_PREFIX__ +#define __STDC_HOSTED__ 1 +#define __LDBL_HAS_INFINITY__ 1 +#define __mips_fpr 32 +#define __FLT_EPSILON__ 1.1920928955078125e-7F +#define __GXX_WEAK__ 1 +#define __mips__ 1 +#define __LDBL_MIN__ 2.2250738585072014e-308L +#define __DEC32_MAX__ 9.999999E96DF +#define MIPSEL 1 +#define __INT32_MAX__ 2147483647 +#define __SIZEOF_LONG__ 4 +#define __DECIMAL_DIG__ 17 +#define __LDBL_HAS_QUIET_NAN__ 1 +#define __GNUC__ 4 +#define __GXX_RTTI 1 +#define __FLT_HAS_DENORM__ 1 +#define __SIZEOF_LONG_DOUBLE__ 8 +#define _R3000 1 +#define __BIGGEST_ALIGNMENT__ 8 +#define __DBL_MAX__ double(1.7976931348623157e+308L) +#define __INT_FAST32_MAX__ 2147483647 +#define __DBL_HAS_INFINITY__ 1 +#define __INT64_MAX__ 9223372036854775807LL +#define __DEC32_MIN_EXP__ (-94) +#define __INT_FAST16_TYPE__ int +#define __LDBL_HAS_DENORM__ 1 +#define __cplusplus 1 +#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL +#define __INT_LEAST32_MAX__ 2147483647 +#define __DEC32_MIN__ 1E-95DF +#define __DEPRECATED 1 +#define __DBL_MAX_EXP__ 1024 +#define __R3000__ 1 +#define __DEC128_EPSILON__ 1E-33DL +#define __PTRDIFF_MAX__ 2147483647 +#define mips 1 +#define __GNUG__ 4 +#define __LANGUAGE_C_PLUS_PLUS__ 1 +#define __LONG_LONG_MAX__ 9223372036854775807LL +#define __SIZEOF_SIZE_T__ 4 +#define __SIZEOF_WINT_T__ 4 +#define __GCC_HAVE_DWARF2_CFI_ASM 1 +#define __GXX_ABI_VERSION 1002 +#define __FLT_MIN_EXP__ (-125) +#define __INT_FAST64_TYPE__ long long int +#define _MIPSEL 1 +#define __DBL_MIN__ double(2.2250738585072014e-308L) +#define _MIPS_ARCH "mips32" +#define __FLT_MIN_10_EXP__ (-37) +#define __DEC128_MIN__ 1E-6143DL +#define __REGISTER_PREFIX__ +#define __UINT16_MAX__ 65535 +#define __DBL_HAS_DENORM__ 1 +#define __UINT8_TYPE__ unsigned char +#define __NO_INLINE__ 1 +#define __R3000 1 +#define __FLT_MANT_DIG__ 24 +#define __VERSION__ "4.6 20120106 (prerelease)" +#define _LANGUAGE_C_PLUS_PLUS 1 +#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __DEC64_EPSILON__ 1E-15DD +#define __ORDER_PDP_ENDIAN__ 3412 +#define __DEC128_MIN_EXP__ (-6142) +#define __INT_FAST32_TYPE__ int +#define __UINT_LEAST16_TYPE__ short unsigned int +#define unix 1 +#define _MIPS_ARCH_MIPS32 1 +#define __INT16_MAX__ 32767 +#define __SIZE_TYPE__ unsigned int +#define __UINT64_MAX__ 18446744073709551615ULL +#define __INT8_TYPE__ signed char +#define __ELF__ 1 +#define __mips_isa_rev 1 +#define _MIPS_TUNE_MIPS32 1 +#define __FLT_RADIX__ 2 +#define __INT_LEAST16_TYPE__ short int +#define __LDBL_EPSILON__ 2.2204460492503131e-16L +#define __SIG_ATOMIC_MAX__ 2147483647 +#define __SIZEOF_PTRDIFF_T__ 4 +#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF +#define __INT_FAST16_MAX__ 2147483647 +#define _MIPS_SZPTR 32 +#define __UINT_FAST32_MAX__ 4294967295U +#define __UINT_LEAST64_TYPE__ long long unsigned int +#define __FLT_HAS_QUIET_NAN__ 1 +#define __FLT_MAX_10_EXP__ 38 +#define __LONG_MAX__ 2147483647L +#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL +#define __FLT_HAS_INFINITY__ 1 +#define __UINT_FAST16_TYPE__ unsigned int +#define __DEC64_MAX__ 9.999999999999999E384DD +#define __CHAR16_TYPE__ short unsigned int +#define __PRAGMA_REDEFINE_EXTNAME 1 +#define __INT_LEAST16_MAX__ 32767 +#define __DEC64_MANT_DIG__ 16 +#define __UINT_LEAST32_MAX__ 4294967295U +#define __INT_LEAST64_TYPE__ long long int +#define __INT16_TYPE__ short int +#define __INT_LEAST8_TYPE__ signed char +#define _mips 1 +#define __DEC32_MAX_EXP__ 97 +#define __INT_FAST8_MAX__ 127 +#define __INTPTR_MAX__ 2147483647 +#define linux 1 +#define _MIPS_SZINT 32 +#define __EXCEPTIONS 1 +#define __LDBL_MANT_DIG__ 53 +#define __DBL_HAS_QUIET_NAN__ 1 +#define __MIPSEL 1 +#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) +#define __GCC_HAVE_BUILTIN_MIPS_CACHE 1 +#define __INTPTR_TYPE__ int +#define __UINT16_TYPE__ short unsigned int +#define __WCHAR_TYPE__ int +#define __SIZEOF_FLOAT__ 4 +#define __pic__ 1 +#define __UINTPTR_MAX__ 4294967295U +#define __DEC64_MIN_EXP__ (-382) +#define __INT_FAST64_MAX__ 9223372036854775807LL +#define __FLT_DIG__ 6 +#define __UINT_FAST64_TYPE__ long long unsigned int +#define __INT_MAX__ 2147483647 +#define __INT64_TYPE__ long long int +#define __FLT_MAX_EXP__ 128 +#define _MIPS_SIM _ABIO32 +#define __DBL_MANT_DIG__ 53 +#define __INT_LEAST64_MAX__ 9223372036854775807LL +#define __DEC64_MIN__ 1E-383DD +#define __WINT_TYPE__ unsigned int +#define __UINT_LEAST32_TYPE__ unsigned int +#define __SIZEOF_SHORT__ 2 +#define __LDBL_MIN_EXP__ (-1021) +#define _MIPS_FPSET 16 +#define __INT_LEAST8_MAX__ 127 +#define __LDBL_MAX_10_EXP__ 308 +#define __DBL_EPSILON__ double(2.2204460492503131e-16L) +#define __INT_LEAST32_TYPE__ int +#define __SIZEOF_WCHAR_T__ 4 +#define __UINT64_TYPE__ long long unsigned int +#define __INT_FAST8_TYPE__ signed char +#define __DBL_DECIMAL_DIG__ 17 +#define __DEC_EVAL_METHOD__ 2 +#define __ORDER_BIG_ENDIAN__ 4321 +#define __INTMAX_MAX__ 9223372036854775807LL +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __FLT_DENORM_MIN__ 1.4012984643248171e-45F +#define __INT8_MAX__ 127 +#define __PIC__ 1 +#define __UINT_FAST32_TYPE__ unsigned int +#define __CHAR32_TYPE__ unsigned int +#define __FLT_MAX__ 3.4028234663852886e+38F +#define __INT32_TYPE__ int +#define __SIZEOF_DOUBLE__ 8 +#define __INTMAX_TYPE__ long long int +#define __DEC128_MAX_EXP__ 6145 +#define __GNUC_MINOR__ 6 +#define __UINTMAX_MAX__ 18446744073709551615ULL +#define __DEC32_MANT_DIG__ 7 +#define __DBL_MAX_10_EXP__ 308 +#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L +#define __STDC__ 1 +#define __mips_hard_float 1 +#define __PTRDIFF_TYPE__ int +#define __mips 32 +#define __UINT32_TYPE__ unsigned int +#define _MIPS_SZLONG 32 +#define __UINTPTR_TYPE__ unsigned int +#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD +#define __DEC128_MANT_DIG__ 34 +#define __LDBL_MIN_10_EXP__ (-307) +#define __SIZEOF_LONG_LONG__ 8 +#define __LDBL_DIG__ 15 +#define __FLT_DECIMAL_DIG__ 9 +#define __UINT_FAST16_MAX__ 4294967295U +#define __GNUC_GNU_INLINE__ 1 +#define __UINT_FAST8_TYPE__ unsigned char +#define _GNU_SOURCE 1 +#define ANDROID +#endif + +// --- Include directories begin --- // +//C:/Android/ndk/platforms/android-9/arch-mips/usr/include +//C:\Android\ndk\toolchains\mipsel-linux-android-4.6\prebuilt\windows\bin\../lib/gcc/mipsel-linux-android/4.6/include +//C:\Android\ndk\toolchains\mipsel-linux-android-4.6\prebuilt\windows\bin\../lib/gcc/mipsel-linux-android/4.6/include-fixed +// --- Library directories end --- // + + +// --- Library directories begin --- // +//C:/Android/ndk/toolchains/mipsel-linux-android-4.6/prebuilt/windows/bin/../lib/gcc/mipsel-linux-android/4.6/ +//C:/Android/ndk/toolchains/mipsel-linux-android-4.6/prebuilt/windows/bin/../lib/gcc/ +//C:/Android/ndk/toolchains/mipsel-linux-android-4.6/prebuilt/windows/bin/../lib/gcc/mipsel-linux-android/4.6/../../../../mipsel-linux-android/lib/ +// --- Library directories begin --- // + diff --git a/Graphics/GraphicsEngine/build/Windows/Android/gcc_Release.h b/Graphics/GraphicsEngine/build/Windows/Android/gcc_Release.h new file mode 100644 index 00000000..da574716 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/Android/gcc_Release.h @@ -0,0 +1,249 @@ +/* + This file is only used by IntelliSense (VisualStudio code suggestion system) + DO NOT INCLUDE THIS FILE FROM YOUR ACTUAL SOURCE FILES. + This file lists the preprocessor macros extracted from your GCC. + It is needed for IntelliSense to parse other header files correctly. +*/ +#ifdef _MSC_VER +#define __DBL_MIN_EXP__ (-1021) +#define __UINT_LEAST16_MAX__ 65535 +#define __FLT_MIN__ 1.1754943508222875e-38F +#define __UINT_LEAST8_TYPE__ unsigned char +#define __CHAR_BIT__ 8 +#define __UINT8_MAX__ 255 +#define __ANDROID__ 1 +#define __WINT_MAX__ 4294967295U +#define R3000 1 +#define __ORDER_LITTLE_ENDIAN__ 1234 +#define __SIZE_MAX__ 4294967295U +#define __WCHAR_MAX__ 2147483647 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +#define __DBL_DENORM_MIN__ double(4.9406564584124654e-324L) +#define __FLT_EVAL_METHOD__ 0 +#define __unix__ 1 +#define _MIPS_ISA _MIPS_ISA_MIPS32 +#define __UINT_FAST64_MAX__ 18446744073709551615ULL +#define __SIG_ATOMIC_TYPE__ int +#define __DBL_MIN_10_EXP__ (-307) +#define __FINITE_MATH_ONLY__ 0 +#define _MIPS_TUNE "mips32" +#define _ABIO32 1 +#define __GNUC_PATCHLEVEL__ 0 +#define __UINT_FAST8_MAX__ 255 +#define __DEC64_MAX_EXP__ 385 +#define __UINT_LEAST64_MAX__ 18446744073709551615ULL +#define __SHRT_MAX__ 32767 +#define __LDBL_MAX__ 1.7976931348623157e+308L +#define __UINT_LEAST8_MAX__ 255 +#define __mips_abicalls 1 +#define __UINTMAX_TYPE__ long long unsigned int +#define __linux 1 +#define __DEC32_EPSILON__ 1E-6DF +#define __unix 1 +#define __UINT32_MAX__ 4294967295U +#define __LDBL_MAX_EXP__ 1024 +#define __LANGUAGE_C_PLUS_PLUS 1 +#define __WINT_MIN__ 0U +#define __MIPSEL__ 1 +#define __linux__ 1 +#define __SCHAR_MAX__ 127 +#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) +#define __DBL_DIG__ 15 +#define __SIZEOF_INT__ 4 +#define __SIZEOF_POINTER__ 4 +#define __USER_LABEL_PREFIX__ +#define __STDC_HOSTED__ 1 +#define __LDBL_HAS_INFINITY__ 1 +#define __mips_fpr 32 +#define __FLT_EPSILON__ 1.1920928955078125e-7F +#define __GXX_WEAK__ 1 +#define __mips__ 1 +#define __LDBL_MIN__ 2.2250738585072014e-308L +#define __DEC32_MAX__ 9.999999E96DF +#define MIPSEL 1 +#define __INT32_MAX__ 2147483647 +#define __SIZEOF_LONG__ 4 +#define __DECIMAL_DIG__ 17 +#define __LDBL_HAS_QUIET_NAN__ 1 +#define __GNUC__ 4 +#define __GXX_RTTI 1 +#define __FLT_HAS_DENORM__ 1 +#define __SIZEOF_LONG_DOUBLE__ 8 +#define _R3000 1 +#define __BIGGEST_ALIGNMENT__ 8 +#define __DBL_MAX__ double(1.7976931348623157e+308L) +#define __INT_FAST32_MAX__ 2147483647 +#define __DBL_HAS_INFINITY__ 1 +#define __INT64_MAX__ 9223372036854775807LL +#define __DEC32_MIN_EXP__ (-94) +#define __INT_FAST16_TYPE__ int +#define __LDBL_HAS_DENORM__ 1 +#define __cplusplus 1 +#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL +#define __INT_LEAST32_MAX__ 2147483647 +#define __DEC32_MIN__ 1E-95DF +#define __DEPRECATED 1 +#define __DBL_MAX_EXP__ 1024 +#define __R3000__ 1 +#define __DEC128_EPSILON__ 1E-33DL +#define __PTRDIFF_MAX__ 2147483647 +#define mips 1 +#define __GNUG__ 4 +#define __LANGUAGE_C_PLUS_PLUS__ 1 +#define __LONG_LONG_MAX__ 9223372036854775807LL +#define __SIZEOF_SIZE_T__ 4 +#define __SIZEOF_WINT_T__ 4 +#define __GCC_HAVE_DWARF2_CFI_ASM 1 +#define __GXX_ABI_VERSION 1002 +#define __FLT_MIN_EXP__ (-125) +#define __INT_FAST64_TYPE__ long long int +#define _MIPSEL 1 +#define __DBL_MIN__ double(2.2250738585072014e-308L) +#define _MIPS_ARCH "mips32" +#define __FLT_MIN_10_EXP__ (-37) +#define __DEC128_MIN__ 1E-6143DL +#define __REGISTER_PREFIX__ +#define __UINT16_MAX__ 65535 +#define __DBL_HAS_DENORM__ 1 +#define __UINT8_TYPE__ unsigned char +#define __NO_INLINE__ 1 +#define __R3000 1 +#define __FLT_MANT_DIG__ 24 +#define __VERSION__ "4.6 20120106 (prerelease)" +#define _LANGUAGE_C_PLUS_PLUS 1 +#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __DEC64_EPSILON__ 1E-15DD +#define __ORDER_PDP_ENDIAN__ 3412 +#define __DEC128_MIN_EXP__ (-6142) +#define __INT_FAST32_TYPE__ int +#define __UINT_LEAST16_TYPE__ short unsigned int +#define unix 1 +#define _MIPS_ARCH_MIPS32 1 +#define __INT16_MAX__ 32767 +#define __SIZE_TYPE__ unsigned int +#define __UINT64_MAX__ 18446744073709551615ULL +#define __INT8_TYPE__ signed char +#define __ELF__ 1 +#define __mips_isa_rev 1 +#define _MIPS_TUNE_MIPS32 1 +#define __FLT_RADIX__ 2 +#define __INT_LEAST16_TYPE__ short int +#define __LDBL_EPSILON__ 2.2204460492503131e-16L +#define __SIG_ATOMIC_MAX__ 2147483647 +#define __SIZEOF_PTRDIFF_T__ 4 +#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF +#define __INT_FAST16_MAX__ 2147483647 +#define _MIPS_SZPTR 32 +#define __UINT_FAST32_MAX__ 4294967295U +#define __UINT_LEAST64_TYPE__ long long unsigned int +#define __FLT_HAS_QUIET_NAN__ 1 +#define __FLT_MAX_10_EXP__ 38 +#define __LONG_MAX__ 2147483647L +#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL +#define __FLT_HAS_INFINITY__ 1 +#define __UINT_FAST16_TYPE__ unsigned int +#define __DEC64_MAX__ 9.999999999999999E384DD +#define __CHAR16_TYPE__ short unsigned int +#define __PRAGMA_REDEFINE_EXTNAME 1 +#define __INT_LEAST16_MAX__ 32767 +#define __DEC64_MANT_DIG__ 16 +#define __UINT_LEAST32_MAX__ 4294967295U +#define __INT_LEAST64_TYPE__ long long int +#define __INT16_TYPE__ short int +#define __INT_LEAST8_TYPE__ signed char +#define _mips 1 +#define __DEC32_MAX_EXP__ 97 +#define __INT_FAST8_MAX__ 127 +#define __INTPTR_MAX__ 2147483647 +#define linux 1 +#define _MIPS_SZINT 32 +#define __EXCEPTIONS 1 +#define __LDBL_MANT_DIG__ 53 +#define __DBL_HAS_QUIET_NAN__ 1 +#define __MIPSEL 1 +#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) +#define __GCC_HAVE_BUILTIN_MIPS_CACHE 1 +#define __INTPTR_TYPE__ int +#define __UINT16_TYPE__ short unsigned int +#define __WCHAR_TYPE__ int +#define __SIZEOF_FLOAT__ 4 +#define __pic__ 1 +#define __UINTPTR_MAX__ 4294967295U +#define __DEC64_MIN_EXP__ (-382) +#define __INT_FAST64_MAX__ 9223372036854775807LL +#define __FLT_DIG__ 6 +#define __UINT_FAST64_TYPE__ long long unsigned int +#define __INT_MAX__ 2147483647 +#define __INT64_TYPE__ long long int +#define __FLT_MAX_EXP__ 128 +#define _MIPS_SIM _ABIO32 +#define __DBL_MANT_DIG__ 53 +#define __INT_LEAST64_MAX__ 9223372036854775807LL +#define __DEC64_MIN__ 1E-383DD +#define __WINT_TYPE__ unsigned int +#define __UINT_LEAST32_TYPE__ unsigned int +#define __SIZEOF_SHORT__ 2 +#define __LDBL_MIN_EXP__ (-1021) +#define _MIPS_FPSET 16 +#define __INT_LEAST8_MAX__ 127 +#define __LDBL_MAX_10_EXP__ 308 +#define __DBL_EPSILON__ double(2.2204460492503131e-16L) +#define __INT_LEAST32_TYPE__ int +#define __SIZEOF_WCHAR_T__ 4 +#define __UINT64_TYPE__ long long unsigned int +#define __INT_FAST8_TYPE__ signed char +#define __DBL_DECIMAL_DIG__ 17 +#define __DEC_EVAL_METHOD__ 2 +#define __ORDER_BIG_ENDIAN__ 4321 +#define __INTMAX_MAX__ 9223372036854775807LL +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __FLT_DENORM_MIN__ 1.4012984643248171e-45F +#define __INT8_MAX__ 127 +#define __PIC__ 1 +#define __UINT_FAST32_TYPE__ unsigned int +#define __CHAR32_TYPE__ unsigned int +#define __FLT_MAX__ 3.4028234663852886e+38F +#define __INT32_TYPE__ int +#define __SIZEOF_DOUBLE__ 8 +#define __INTMAX_TYPE__ long long int +#define __DEC128_MAX_EXP__ 6145 +#define __GNUC_MINOR__ 6 +#define __UINTMAX_MAX__ 18446744073709551615ULL +#define __DEC32_MANT_DIG__ 7 +#define __DBL_MAX_10_EXP__ 308 +#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L +#define __STDC__ 1 +#define __mips_hard_float 1 +#define __PTRDIFF_TYPE__ int +#define __mips 32 +#define __UINT32_TYPE__ unsigned int +#define _MIPS_SZLONG 32 +#define __UINTPTR_TYPE__ unsigned int +#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD +#define __DEC128_MANT_DIG__ 34 +#define __LDBL_MIN_10_EXP__ (-307) +#define __SIZEOF_LONG_LONG__ 8 +#define __LDBL_DIG__ 15 +#define __FLT_DECIMAL_DIG__ 9 +#define __UINT_FAST16_MAX__ 4294967295U +#define __GNUC_GNU_INLINE__ 1 +#define __UINT_FAST8_TYPE__ unsigned char +#define _GNU_SOURCE 1 +#define ANDROID +#endif + +// --- Include directories begin --- // +//C:/Android/ndk/platforms/android-9/arch-mips/usr/include +//C:\Android\ndk\toolchains\mipsel-linux-android-4.6\prebuilt\windows\bin\../lib/gcc/mipsel-linux-android/4.6/include +//C:\Android\ndk\toolchains\mipsel-linux-android-4.6\prebuilt\windows\bin\../lib/gcc/mipsel-linux-android/4.6/include-fixed +// --- Library directories end --- // + + +// --- Library directories begin --- // +//C:/Android/ndk/toolchains/mipsel-linux-android-4.6/prebuilt/windows/bin/../lib/gcc/mipsel-linux-android/4.6/ +//C:/Android/ndk/toolchains/mipsel-linux-android-4.6/prebuilt/windows/bin/../lib/gcc/ +//C:/Android/ndk/toolchains/mipsel-linux-android-4.6/prebuilt/windows/bin/../lib/gcc/mipsel-linux-android/4.6/../../../../mipsel-linux-android/lib/ +// --- Library directories begin --- // + diff --git a/Graphics/GraphicsEngine/build/Windows/EngineRoot.props b/Graphics/GraphicsEngine/build/Windows/EngineRoot.props new file mode 100644 index 00000000..6e4b958b --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/EngineRoot.props @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..</GraphicsRoot> + </PropertyGroup> + <PropertyGroup /> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Debug.vgdbsettings b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Debug.vgdbsettings new file mode 100644 index 00000000..3f5b24b1 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Debug.vgdbsettings @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<VisualGDBProjectSettings2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <ConfigurationName>Debug</ConfigurationName> + <Project xsi:type="com.visualgdb.project.android"> + <CustomSourceDirectories> + <Directories /> + <PathStyle>MinGWWindowsSlash</PathStyle> + </CustomSourceDirectories> + <AndroidProjectPath>$(ProjectDir)</AndroidProjectPath> + </Project> + <Build xsi:type="com.visualgdb.build.android"> + <AndroidPlatform>android-19</AndroidPlatform> + <IsDebugConfiguration>true</IsDebugConfiguration> + <JNIOnlyBuild>true</JNIOnlyBuild> + <AdditionalDirectoriesToDeleteOnClean>bin;obj</AdditionalDirectoriesToDeleteOnClean> + <DeleteANTFilesOnClean>false</DeleteANTFilesOnClean> + <DoNotEditAndroidManifest>false</DoNotEditAndroidManifest> + <CustomActions /> + </Build> + <Debug xsi:type="com.visualgdb.debug.android"> + <AdditionalStartupCommands /> + <AdditionalGDBSettings> + <FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications> + <ForceSingleThreadedMode>false</ForceSingleThreadedMode> + <PendingBreakpointsSupported>true</PendingBreakpointsSupported> + <DisableChildRanges>false</DisableChildRanges> + <UseAppleExtensions>false</UseAppleExtensions> + <CanAcceptCommandsWhileRunning>false</CanAcceptCommandsWhileRunning> + <MakeLogFile>false</MakeLogFile> + <IgnoreModuleEventsWhileStepping>true</IgnoreModuleEventsWhileStepping> + <UseRelativePathsOnly>false</UseRelativePathsOnly> + <ExitAction>KillApp</ExitAction> + <Features> + <DisableAutoDetection>false</DisableAutoDetection> + <UseFrameParameter>false</UseFrameParameter> + <SimpleValuesFlagSupported>false</SimpleValuesFlagSupported> + <ListLocalsSupported>false</ListLocalsSupported> + <ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable> + <ThreadInfoSupported>false</ThreadInfoSupported> + <PendingBreakpointsSupported>false</PendingBreakpointsSupported> + <SupportTargetCommand>false</SupportTargetCommand> + </Features> + <DisableDisassembly>false</DisableDisassembly> + <ExamineMemoryWithXCommand>false</ExamineMemoryWithXCommand> + <StepIntoNewInstanceEntry>main</StepIntoNewInstanceEntry> + <ExamineRegistersInRawFormat>true</ExamineRegistersInRawFormat> + </AdditionalGDBSettings> + <LaunchGDBSettings xsi:type="GDBLaunchParametersAndroid" /> + <GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC> + <UseDefaultInstallDir>false</UseDefaultInstallDir> + <RemotePort>5039</RemotePort> + <LocalPort>5039</LocalPort> + <GDBServerStartupTimeout>10000</GDBServerStartupTimeout> + <AdditionalGDBServerStartupDelay>0</AdditionalGDBServerStartupDelay> + <DoubleSlashWorkaround>false</DoubleSlashWorkaround> + <AlreadyRunningDecision>Ask</AlreadyRunningDecision> + <ShowLogCat>true</ShowLogCat> + <EnableThreadNameWatcher>true</EnableThreadNameWatcher> + </Debug> + <CustomBuild> + <PreBuildActions /> + <PostBuildActions /> + <PreCleanActions /> + <PostCleanActions /> + </CustomBuild> + <CustomDebug> + <PreDebugActions /> + <PostDebugActions /> + <BreakMode>Default</BreakMode> + </CustomDebug> + <CustomShortcuts> + <Shortcuts /> + <ShowMessageAfterExecuting>true</ShowMessageAfterExecuting> + </CustomShortcuts> + <UserDefinedVariables /> +</VisualGDBProjectSettings2>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Release.vgdbsettings b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Release.vgdbsettings new file mode 100644 index 00000000..669691f2 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Release.vgdbsettings @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<VisualGDBProjectSettings2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <ConfigurationName>Release</ConfigurationName> + <Project xsi:type="com.visualgdb.project.android"> + <CustomSourceDirectories> + <Directories /> + <PathStyle>MinGWWindowsSlash</PathStyle> + </CustomSourceDirectories> + <AndroidProjectPath>$(ProjectDir)</AndroidProjectPath> + </Project> + <Build xsi:type="com.visualgdb.build.android"> + <AndroidPlatform>android-19</AndroidPlatform> + <IsDebugConfiguration>false</IsDebugConfiguration> + <JNIOnlyBuild>true</JNIOnlyBuild> + <AdditionalDirectoriesToDeleteOnClean>bin;obj</AdditionalDirectoriesToDeleteOnClean> + <DeleteANTFilesOnClean>false</DeleteANTFilesOnClean> + <DoNotEditAndroidManifest>false</DoNotEditAndroidManifest> + <CustomActions /> + </Build> + <Debug xsi:type="com.visualgdb.debug.android"> + <AdditionalStartupCommands /> + <AdditionalGDBSettings> + <FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications> + <ForceSingleThreadedMode>false</ForceSingleThreadedMode> + <PendingBreakpointsSupported>true</PendingBreakpointsSupported> + <DisableChildRanges>false</DisableChildRanges> + <UseAppleExtensions>false</UseAppleExtensions> + <CanAcceptCommandsWhileRunning>false</CanAcceptCommandsWhileRunning> + <MakeLogFile>false</MakeLogFile> + <IgnoreModuleEventsWhileStepping>true</IgnoreModuleEventsWhileStepping> + <UseRelativePathsOnly>false</UseRelativePathsOnly> + <ExitAction>KillApp</ExitAction> + <Features> + <DisableAutoDetection>false</DisableAutoDetection> + <UseFrameParameter>false</UseFrameParameter> + <SimpleValuesFlagSupported>false</SimpleValuesFlagSupported> + <ListLocalsSupported>false</ListLocalsSupported> + <ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable> + <ThreadInfoSupported>false</ThreadInfoSupported> + <PendingBreakpointsSupported>false</PendingBreakpointsSupported> + <SupportTargetCommand>false</SupportTargetCommand> + </Features> + <DisableDisassembly>false</DisableDisassembly> + <ExamineMemoryWithXCommand>false</ExamineMemoryWithXCommand> + <StepIntoNewInstanceEntry>main</StepIntoNewInstanceEntry> + <ExamineRegistersInRawFormat>true</ExamineRegistersInRawFormat> + </AdditionalGDBSettings> + <LaunchGDBSettings xsi:type="GDBLaunchParametersAndroid" /> + <GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC> + <UseDefaultInstallDir>false</UseDefaultInstallDir> + <RemotePort>5039</RemotePort> + <LocalPort>5039</LocalPort> + <GDBServerStartupTimeout>10000</GDBServerStartupTimeout> + <AdditionalGDBServerStartupDelay>0</AdditionalGDBServerStartupDelay> + <DoubleSlashWorkaround>false</DoubleSlashWorkaround> + <AlreadyRunningDecision>Ask</AlreadyRunningDecision> + <ShowLogCat>true</ShowLogCat> + <EnableThreadNameWatcher>true</EnableThreadNameWatcher> + </Debug> + <CustomBuild> + <PreBuildActions /> + <PostBuildActions /> + <PreCleanActions /> + <PostCleanActions /> + </CustomBuild> + <CustomDebug> + <PreDebugActions /> + <PostDebugActions /> + <BreakMode>Default</BreakMode> + </CustomDebug> + <CustomShortcuts> + <Shortcuts /> + <ShowMessageAfterExecuting>true</ShowMessageAfterExecuting> + </CustomShortcuts> + <UserDefinedVariables /> +</VisualGDBProjectSettings2>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.props b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.props new file mode 100644 index 00000000..f5ff61e5 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.props @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup /> + <ItemGroup /> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj new file mode 100644 index 00000000..34dfc85e --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{052DD700-477C-4512-A7F4-B05EBEF5C80E}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>RenderEngine</RootNamespace> + <ProjectName>GraphicsEngine</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + <Import Project="..\WindowsStore\GraphicsEngine.Shared\GraphicsEngine.Shared.vcxitems" Label="Shared" Condition="Exists('..\WindowsStore\GraphicsEngine.Shared\GraphicsEngine.Shared.vcxitems')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="..\..\..\..\Shared\build\Windows\Android32d.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="..\..\..\..\Shared\build\Windows\Android32r.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <NMakeForcedIncludes>$(ProjectDir)\Android\gcc_Debug.h;$(NMakeForcedIncludes)</NMakeForcedIncludes> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <NMakeForcedIncludes>$(ProjectDir)\Android\gcc_Release.h;$(NMakeForcedIncludes)</NMakeForcedIncludes> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <Lib> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <Lib> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <None Include="jni\Android.mk" /> + <None Include="jni\Application.mk" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\ResourceMapping.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\Texture.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj.filters b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj.filters new file mode 100644 index 00000000..f9817491 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="jni"> + <UniqueIdentifier>{8939e7b7-453a-4762-9f92-ad0a2915609f}</UniqueIdentifier> + </Filter> + <Filter Include="android_src"> + <UniqueIdentifier>{551d0b50-542f-47e1-8e7b-6b382176f2b1}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <None Include="jni\Application.mk"> + <Filter>jni</Filter> + </None> + <None Include="jni\Android.mk"> + <Filter>jni</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\ResourceMapping.cpp"> + <Filter>android_src</Filter> + </ClCompile> + <ClCompile Include="..\..\src\Texture.cpp"> + <Filter>android_src</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/jni/Android.mk b/Graphics/GraphicsEngine/build/Windows/jni/Android.mk new file mode 100644 index 00000000..5d40b9a3 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/jni/Android.mk @@ -0,0 +1,24 @@ +# Android NDK project makefile autogenerated by Premake + +# Preamble +DEPENDENCY_PATH := $(call my-dir) +LOCAL_PATH := $(abspath $(DEPENDENCY_PATH)) +include $(CLEAR_VARS) + + +# Project configuration +LOCAL_MODULE := GraphicsEngine +LOCAL_CFLAGS := -std=c++11 +LOCAL_CPP_FEATURES := exceptions +LOCAL_STATIC_LIBRARIES += + +# Include paths +PROJECT_ROOT := $(LOCAL_PATH)/../../.. +SOLUTION_ROOT := $(PROJECT_ROOT)/../.. +LOCAL_C_INCLUDES := $(PROJECT_ROOT)/include $(PROJECT_ROOT)/interface $(SOLUTION_ROOT)/Common/include $(SOLUTION_ROOT)/Common/interface $(SOLUTION_ROOT)/Platforms/interface $(SOLUTION_ROOT)/Graphics/GraphicsTools/include + +# Source files +#VisualGDBAndroid: AutoUpdateSourcesInNextLine +LOCAL_SRC_FILES := ../../../src/ResourceMapping.cpp ../../../src/Texture.cpp + +include $(BUILD_STATIC_LIBRARY) diff --git a/Graphics/GraphicsEngine/build/Windows/jni/Application.mk b/Graphics/GraphicsEngine/build/Windows/jni/Application.mk new file mode 100644 index 00000000..45f02b20 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows/jni/Application.mk @@ -0,0 +1,7 @@ +# Generated by VisualGDB + +DEPENDENCY_PATH := $(call my-dir) +LOCAL_PATH := $(abspath $(DEPENDENCY_PATH)) +include $(LOCAL_PATH)/../../../../../Common/make/AppCommon.mk + +APP_MODULES := GraphicsEngine
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/EngineRoot.props b/Graphics/GraphicsEngine/build/WindowsStore/EngineRoot.props new file mode 100644 index 00000000..fcb891c0 --- /dev/null +++ b/Graphics/GraphicsEngine/build/WindowsStore/EngineRoot.props @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..\..</GraphicsRoot> + </PropertyGroup> + <PropertyGroup /> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems new file mode 100644 index 00000000..e8d4f5a7 --- /dev/null +++ b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <ItemsProjectGuid>{0cdd843c-089d-4fee-be9f-c08fa2b51acb}</ItemsProjectGuid> + <ItemsRootNamespace>GraphicsEngine</ItemsRootNamespace> + <ItemsProjectName>GraphicsEngine.Shared</ItemsProjectName> + <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectCapability Include="SourceItemsFromImports" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\ResourceMapping.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BlendStateBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferViewBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Defines.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DepthStencilStateBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceContextBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceObjectBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RasterizerStateBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RenderDeviceBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ResourceMappingImpl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SamplerBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\StateObjectsRegistry.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SwapChainBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureViewBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\VertexDescriptionBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BlendState.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Buffer.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferView.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Constants.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DepthStencilState.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceCaps.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceContext.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceObject.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\MapHelper.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RasterizerState.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDevice.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\ResourceMapping.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Sampler.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Shader.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SwapChain.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Texture.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureView.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\GraphicsTypes.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\VertexDescription.h" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems.filters b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems.filters new file mode 100644 index 00000000..8014c299 --- /dev/null +++ b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems.filters @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="include"> + <UniqueIdentifier>{32eded03-121f-406a-8a23-6721ca9116ee}</UniqueIdentifier> + </Filter> + <Filter Include="src"> + <UniqueIdentifier>{d881c412-cc78-41fb-997c-0d6543c1e477}</UniqueIdentifier> + </Filter> + <Filter Include="interface"> + <UniqueIdentifier>{c38a8d65-5100-44be-b1a5-453d901c892f}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\ResourceMapping.cpp"> + <Filter>src</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceObjectBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RasterizerStateBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RenderDeviceBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ResourceMappingImpl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SamplerBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\StateObjectsRegistry.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureViewBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\VertexDescriptionBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BlendStateBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferViewBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Defines.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DepthStencilStateBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceContextBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DepthStencilState.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceCaps.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceContext.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceObject.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\MapHelper.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RasterizerState.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDevice.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\ResourceMapping.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Sampler.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Shader.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Texture.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureView.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\VertexDescription.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BlendState.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Buffer.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferView.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Constants.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SwapChain.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SwapChainBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\GraphicsTypes.h"> + <Filter>interface</Filter> + </ClInclude> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj new file mode 100644 index 00000000..7a0d8593 --- /dev/null +++ b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj @@ -0,0 +1,209 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9df5553c-ca9d-4cb6-a06a-ca905119c00b}</ProjectGuid> + <RootNamespace>GraphicsEngine</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <AppContainerApplication>true</AppContainerApplication> + <ApplicationType>Windows Store</ApplicationType> + <ApplicationTypeRevision>8.1</ApplicationTypeRevision> + <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="..\GraphicsEngine.Shared\GraphicsEngine.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj.filters b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj.filters new file mode 100644 index 00000000..a7761ab0 --- /dev/null +++ b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj.filters @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + </ItemGroup> +</Project> diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj new file mode 100644 index 00000000..b3f74084 --- /dev/null +++ b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{aefba9a8-e16d-4b06-b16d-bc74ac799b4f}</ProjectGuid> + <RootNamespace>GraphicsEngine</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <AppContainerApplication>true</AppContainerApplication> + <ApplicationType>Windows Phone</ApplicationType> + <ApplicationTypeRevision>8.1</ApplicationTypeRevision> + <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="..\GraphicsEngine.Shared\GraphicsEngine.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngine.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj.filters b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj.filters new file mode 100644 index 00000000..a7761ab0 --- /dev/null +++ b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj.filters @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + </ItemGroup> +</Project> diff --git a/Graphics/GraphicsEngine/include/BlendStateBase.h b/Graphics/GraphicsEngine/include/BlendStateBase.h new file mode 100644 index 00000000..78494b46 --- /dev/null +++ b/Graphics/GraphicsEngine/include/BlendStateBase.h @@ -0,0 +1,76 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::BlendStateBase template class + +#include "BlendState.h" +#include "DeviceObjectBase.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a blend state object. + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IBlendStateD3D11 or Diligent::IBlendStateGL). +/// \tparam RenderDeviceBaseInterface - base interface for the render device +/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceGL, +/// or Diligent::IRenderDeviceGLES). +template<class BaseInterface = IBlendState, class RenderDeviceBaseInterface = IRenderDevice> +class BlendStateBase : public DeviceObjectBase<BaseInterface, BlendStateDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, BlendStateDesc> TDeviceObjectBase; + typedef RenderDeviceBase < RenderDeviceBaseInterface > TRenderDeviceBase; + + /// \param pDevice - pointer to the device. + /// \param BSDesc - blend state description. + /// \param bIsDeviceInternal - flag indicating if the blend state is an internal device object and + /// must not keep a strong reference to the device. + BlendStateBase( IRenderDevice *pDevice, const BlendStateDesc& BSDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pDevice, BSDesc, nullptr, bIsDeviceInternal ) + { + } + + ~BlendStateBase() + { + /// \note Destructor cannot directly remove the object from the registry as this may cause a + /// deadlock at the point where StateObjectsRegistry::Find() locks the weak pointer: if we + /// are in dtor, the object is locked by Diligent::RefCountedObject::Release() and + /// StateObjectsRegistry::Find() will wait for that lock to be released. + /// A the same time this thread will be waiting for the other thread to unlock the registry.\n + /// Thus destructor only notifies the registry that there is a deleted object. + /// The reference to the object will be removed later. + auto &BlendStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetBSRegistry(); + // StateObjectsRegistry::ReportDeletedObject() does not lock the registry, but only + // atomically increments the outstanding deleted objects counter. + BlendStateRegistry.ReportDeletedObject(); + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_BlendState, TDeviceObjectBase ) +}; + +} diff --git a/Graphics/GraphicsEngine/include/BufferBase.h b/Graphics/GraphicsEngine/include/BufferBase.h new file mode 100644 index 00000000..43b07662 --- /dev/null +++ b/Graphics/GraphicsEngine/include/BufferBase.h @@ -0,0 +1,234 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::BufferBase template class + +#include "Buffer.h" +#include "DeviceObjectBase.h" +#include "GraphicsUtilities.h" +#include <memory> + +namespace Diligent +{ + +/// Template class implementing base functionality for a buffer object + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IBufferD3D11 or Diligent::IBufferGL). +/// \tparam BufferViewImplType - type of the buffer view implementation +/// (Diligent::BufferViewD3D11Impl or Diligent::BufferVeiwGLImpl) +template<class BaseInterface, class BufferViewImplType> +class BufferBase : public DeviceObjectBase < BaseInterface, BufferDesc > +{ +public: + typedef DeviceObjectBase<BaseInterface, BufferDesc> TDeviceObjectBase; + + /// \param pDevice - pointer to the device. + /// \param BuffDesc - buffer description. + /// \param bIsDeviceInternal - flag indicating if the buffer is an internal device object and + /// must not keep a strong reference to the device. + BufferBase( IRenderDevice *pDevice, const BufferDesc& BuffDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pDevice, BuffDesc, nullptr, bIsDeviceInternal ) + { + Uint32 AllowedBindFlags = + BIND_VERTEX_BUFFER | BIND_INDEX_BUFFER | BIND_UNIFORM_BUFFER | + BIND_SHADER_RESOURCE | BIND_STREAM_OUTPUT | BIND_UNORDERED_ACCESS | + BIND_INDIRECT_DRAW_ARGS; + const Char* strAllowedBindFlags = + "BIND_VERTEX_BUFFER (1), BIND_INDEX_BUFFER (2), BIND_UNIFORM_BUFFER (4), " + "BIND_SHADER_RESOURCE (8), BIND_STREAM_OUTPUT (16), BIND_UNORDERED_ACCESS (128), " + "BIND_INDIRECT_DRAW_ARGS (256)"; + +#define VERIFY_BUFFER(Expr, ...) VERIFY(Expr, "Buffer \"", m_Desc.Name ? m_Desc.Name : "", "\": ", ##__VA_ARGS__) + + VERIFY_BUFFER( (BuffDesc.BindFlags & ~AllowedBindFlags) == 0, "Incorrect bind flags specified (", BuffDesc.BindFlags & ~AllowedBindFlags, "). Only the following flags are allowed:\n", strAllowedBindFlags ); + + m_Desc = BuffDesc; + if( (m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || + (m_Desc.BindFlags & BIND_SHADER_RESOURCE) ) + { + VERIFY_BUFFER( m_Desc.Mode > BUFFER_MODE_UNDEFINED && m_Desc.Mode < BUFFER_MODE_NUM_MODES, "Buffer mode (", m_Desc.Mode, ") is not correct" ); + if( m_Desc.Mode == BUFFER_MODE_STRUCTURED ) + { + VERIFY_BUFFER( m_Desc.ElementByteStride != 0, "Element stride cannot be zero for structured buffer" ); + } + + if( m_Desc.Mode == BUFFER_MODE_FORMATED ) + { + VERIFY_BUFFER( m_Desc.Format.ValueType != VT_UNDEFINED, "Value type is not specified for a formated buffer" ); + VERIFY_BUFFER( m_Desc.Format.NumComponents != 0, "Num components cannot be zero in a formated buffer" ); + if( m_Desc.ElementByteStride == 0 ) + m_Desc.ElementByteStride = static_cast<Uint32>(GetValueSize( m_Desc.Format.ValueType )) * m_Desc.Format.NumComponents; + } + } + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_Buffer, TDeviceObjectBase ) + + virtual void UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData )override = 0; + + virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size )override = 0; + + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; + + virtual void Unmap( IDeviceContext *pContext )override = 0; + + virtual void CreateView( const struct BufferViewDesc &ViewDesc, IBufferView **ppView )override; + + virtual IBufferView* GetDefaultView( BUFFER_VIEW_TYPE ViewType )override; + + void CreateDefaultViews(); + +protected: + virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, IBufferView **ppView, bool bIsDefaultView ) = 0; + + void CorrectBufferViewDesc( struct BufferViewDesc &ViewDesc ); + + BufferDesc m_Desc; + + std::unique_ptr<BufferViewImplType> m_pDefaultUAV; + std::unique_ptr<BufferViewImplType> m_pDefaultSRV; +}; + +template<class BaseInterface, class BufferViewImplType> +void BufferBase<BaseInterface, BufferViewImplType> :: UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData ) +{ + VERIFY_BUFFER( m_Desc.Usage == USAGE_DEFAULT, "Only default usage buffers can be updated with UpdateData()" ); + VERIFY_BUFFER( Offset < m_Desc.uiSizeInBytes, "Offset (", Offset, ") exceeds the buffer size (", m_Desc.uiSizeInBytes, ")" ); + VERIFY_BUFFER( Size + Offset <= m_Desc.uiSizeInBytes, "Update region [", Offset, ",", Size + Offset, ") is out of buffer bounds [0,",m_Desc.uiSizeInBytes,")" ); +} + +template<class BaseInterface, class BufferViewImplType> +void BufferBase<BaseInterface, BufferViewImplType> :: CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size ) +{ + VERIFY_BUFFER( DstOffset + Size <= m_Desc.uiSizeInBytes, "Destination range [", DstOffset, ",", DstOffset + Size, ") is out of buffer bounds [0,",m_Desc.uiSizeInBytes,")" ); + VERIFY_BUFFER( SrcOffset + Size <= pSrcBuffer->GetDesc().uiSizeInBytes, "Source range [", SrcOffset, ",", SrcOffset + Size, ") is out of buffer bounds [0,",m_Desc.uiSizeInBytes,")" ); +} + + +template<class BaseInterface, class BufferViewImplType> +void BufferBase<BaseInterface, BufferViewImplType> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) +{ + switch( MapType ) + { + case MAP_READ: + VERIFY_BUFFER( m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read from" ); + VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_READ), "Buffer being mapped for reading was not created with CPU_ACCESS_READ flag" ); + break; + + case MAP_WRITE: + VERIFY_BUFFER( m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be written to" ); + VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Buffer being mapped for writing was not created with CPU_ACCESS_WRITE flag" ); + break; + + case MAP_READ_WRITE: + VERIFY_BUFFER( m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read and written" ); + VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Buffer being mapped for reading & writing was not created with CPU_ACCESS_WRITE flag" ); + VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_READ), "Buffer being mapped for reading & writing was not created with CPU_ACCESS_READ flag" ); + break; + + case MAP_WRITE_DISCARD: + VERIFY_BUFFER( m_Desc.Usage == USAGE_DYNAMIC, "Only dynamic buffers can be mapped with write discard flag" ); + VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" ); + break; + + case MAP_WRITE_NO_OVERWRITE: + VERIFY_BUFFER( m_Desc.Usage == USAGE_DYNAMIC, "Only dynamic buffers can be mapped with write no overwrite flag" ); + VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" ); + break; + + default: UNEXPECTED( "Unknown map type" ); + } +} + +template<class BaseInterface, class BufferViewImplType> +void BufferBase<BaseInterface, BufferViewImplType> :: Unmap( IDeviceContext *pContext ) +{ + +} + + +template<class BaseInterface, class BufferViewImplType> +void BufferBase<BaseInterface, BufferViewImplType> :: CreateView( const struct BufferViewDesc &ViewDesc, IBufferView **ppView ) +{ + CreateViewInternal( ViewDesc, ppView, false ); +} + + +template<class BaseInterface, class BufferViewImplType> +void BufferBase<BaseInterface, BufferViewImplType> :: CorrectBufferViewDesc( struct BufferViewDesc &ViewDesc ) +{ + if( ViewDesc.ByteWidth == 0 ) + ViewDesc.ByteWidth = m_Desc.uiSizeInBytes; + if( ViewDesc.ByteOffset + ViewDesc.ByteWidth > m_Desc.uiSizeInBytes ) + LOG_ERROR_AND_THROW( "Buffer view range [", ViewDesc.ByteOffset, ", ", ViewDesc.ByteOffset + ViewDesc.ByteWidth, ") is out of the buffer boundaries [0, ", m_Desc.uiSizeInBytes, ")." ); + if( (m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || + (m_Desc.BindFlags & BIND_SHADER_RESOURCE) ) + { + VERIFY( m_Desc.ElementByteStride != 0, "Element byte stride is zero" ); + if( (ViewDesc.ByteOffset % m_Desc.ElementByteStride) != 0 ) + LOG_ERROR_AND_THROW( "Buffer view byte offset (", ViewDesc.ByteOffset, ") is not multiple of element byte stride (", m_Desc.ElementByteStride, ")." ); + if( (ViewDesc.ByteWidth % m_Desc.ElementByteStride) != 0 ) + LOG_ERROR_AND_THROW( "Buffer view byte width (", ViewDesc.ByteWidth, ") is not multiple of element byte stride (", m_Desc.ElementByteStride, ")." ); + } +} + +template<class BaseInterface, class BufferViewImplType> +IBufferView* BufferBase<BaseInterface, BufferViewImplType> ::GetDefaultView( BUFFER_VIEW_TYPE ViewType ) +{ + switch( ViewType ) + { + case BUFFER_VIEW_SHADER_RESOURCE: return m_pDefaultSRV.get(); + case BUFFER_VIEW_UNORDERED_ACCESS: return m_pDefaultUAV.get(); + default: UNEXPECTED( "Unknown view type" ); return nullptr; + } +} + +template<class BaseInterface, class BufferViewImplType> +void BufferBase<BaseInterface, BufferViewImplType> :: CreateDefaultViews() +{ + if( m_Desc.BindFlags & BIND_UNORDERED_ACCESS ) + { + BufferViewDesc ViewDesc; + ViewDesc.ViewType = BUFFER_VIEW_UNORDERED_ACCESS; + IBufferView *pUAV = nullptr; + CreateViewInternal( ViewDesc, &pUAV, true ); + m_pDefaultUAV.reset( static_cast<BufferViewImplType*>(pUAV) ); + VERIFY( m_pDefaultUAV->GetDesc().ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Unexpected view type" ); + } + + if( m_Desc.BindFlags & BIND_SHADER_RESOURCE ) + { + BufferViewDesc ViewDesc; + ViewDesc.ViewType = BUFFER_VIEW_SHADER_RESOURCE; + IBufferView* pSRV = nullptr; + CreateViewInternal( ViewDesc, &pSRV, true ); + m_pDefaultSRV.reset( static_cast<BufferViewImplType*>(pSRV) ); + VERIFY( m_pDefaultSRV->GetDesc().ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Unexpected view type" ); + } +} + +} diff --git a/Graphics/GraphicsEngine/include/BufferViewBase.h b/Graphics/GraphicsEngine/include/BufferViewBase.h new file mode 100644 index 00000000..59ce395a --- /dev/null +++ b/Graphics/GraphicsEngine/include/BufferViewBase.h @@ -0,0 +1,83 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::BufferViewBase template class + +#include "BufferView.h" +#include "DeviceObjectBase.h" +#include "GraphicsTypes.h" +#include "RefCntAutoPtr.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a buffer view object + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IBufferViewD3D11 or Diligent::IBufferViewGL). +template<class BaseInterface = IBufferView> +class BufferViewBase : public DeviceObjectBase<BaseInterface, BufferViewDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, BufferViewDesc> TDeviceObjectBase; + + /// \param pDevice - pointer to the render device. + /// \param ViewDesc - buffer view description. + /// \param pBuffer - pointer to the buffer that the view is to be created for. + /// \param bIsDefaultView - flag indicating if the view is default view, and is thus + /// part of the buffer object. In this case the view will attach + /// to the buffer's reference counters. + BufferViewBase( class IRenderDevice *pDevice, + const BufferViewDesc& ViewDesc, + class IBuffer *pBuffer, + bool bIsDefaultView ) : + // Default views are created as part of the buffer, so we cannot not keep strong + // reference to the buffer to avoid cyclic links. Instead, we will attach to the + // reference counters of the buffer. + TDeviceObjectBase( pDevice, ViewDesc, bIsDefaultView ? pBuffer : nullptr ), + m_pBuffer( pBuffer ), + // For non-default view, we will keep strong reference to buffer + m_spBuffer(bIsDefaultView ? nullptr : pBuffer) + {} + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_BufferView, TDeviceObjectBase ) + + virtual IBuffer* GetBuffer() + { + return m_pBuffer; + } + +protected: + + /// Reference to the buffer + IBuffer* m_pBuffer; + + /// Strong reference to the buffer. Used for non-default views + /// to keep the buffer alive + Diligent::RefCntAutoPtr<IBuffer> m_spBuffer; +}; + +} diff --git a/Graphics/GraphicsEngine/include/Defines.h b/Graphics/GraphicsEngine/include/Defines.h new file mode 100644 index 00000000..7f6a56e3 --- /dev/null +++ b/Graphics/GraphicsEngine/include/Defines.h @@ -0,0 +1,25 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + diff --git a/Graphics/GraphicsEngine/include/DepthStencilStateBase.h b/Graphics/GraphicsEngine/include/DepthStencilStateBase.h new file mode 100644 index 00000000..dbfe43d3 --- /dev/null +++ b/Graphics/GraphicsEngine/include/DepthStencilStateBase.h @@ -0,0 +1,69 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::DepthStencilStateBase template class + +#include "DepthStencilState.h" +#include "DeviceObjectBase.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a depth stencil state object. + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IDepthStencilStateD3D11 or Diligent::IDepthStencilStateGL). +/// \tparam RenderDeviceBaseInterface - base interface for the render device +/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceGL, +/// or Diligent::IRenderDeviceGLES). +template<class BaseInterface = IDepthStencilState, class RenderDeviceBaseInterface = IRenderDevice> +class DepthStencilStateBase : public DeviceObjectBase<BaseInterface, DepthStencilStateDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, DepthStencilStateDesc> TDeviceObjectBase; + typedef RenderDeviceBase<RenderDeviceBaseInterface> TRenderDeviceBase; + + /// \param pDevice - pointer to the device. + /// \param DSSDesc - depth-stencil state description. + /// \param bIsDeviceInternal - flag indicating if the state is an internal device object and + /// must not keep a strong reference to the device. + DepthStencilStateBase( IRenderDevice *pDevice, const DepthStencilStateDesc& DSSDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pDevice, DSSDesc, nullptr, bIsDeviceInternal ) + { + } + + ~DepthStencilStateBase() + { + /// \note Destructor cannot directly remove the object from the registry as this may cause a + /// deadlock. See BlendStateBase::~BlendStateBase() for details. + auto &DSStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetDSStateRegistry(); + DSStateRegistry.ReportDeletedObject(); + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DepthStencilState, TDeviceObjectBase ) +}; + +} diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h new file mode 100644 index 00000000..26885aa4 --- /dev/null +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h @@ -0,0 +1,659 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::DeviceContextBase template class and related structures + +#include "DeviceContext.h" +#include "DeviceObjectBase.h" +#include "Defines.h" +#include "ResourceMapping.h" +#include "Sampler.h" +#include "ObjectBase.h" +#include "DebugUtilities.h" +#include "SwapChain.h" +#include "ValidatedCast.h" +#include "GraphicsUtilities.h" + +#ifdef _DEBUG +# define DEBUG_CHECKS +#endif + +namespace Diligent +{ + +/// Describes input vertex stream +struct VertexStreamInfo +{ + /// Strong reference to the buffer object + RefCntAutoPtr<IBuffer> pBuffer; + Uint32 Stride; ///< Stride + Uint32 Offset; ///< Offset + VertexStreamInfo() : + Stride( 0 ), + Offset( 0 ) + {} +}; + +/// Base implementation of the device context. + +/// \tparam BaseInterface - base interface that this class will inheret. +/// \remarks Device context keeps strong references to all objects currently bound to +/// the pipeline: buffers, states, samplers, shaders, etc. +/// The context also keeps strong references to the device and +/// the swap chain. +template<typename BaseInterface = IDeviceContext> +class DeviceContextBase : public ObjectBase<BaseInterface> +{ +public: + DeviceContextBase(IRenderDevice *pRenderDevice) : + m_pDevice(pRenderDevice), + m_IndexDataStartOffset( 0 ), + m_StencilRef( 0 ), + m_SamplesBlendMask( 0 ) + { + for( int i = 0; i < 4; ++i ) + m_BlendFactors[i] = -1; + m_VertexStreams.reserve( MaxBufferSlots ); + m_Viewports.reserve( 16 ); + m_ScissorRects.reserve( 16 ); + // Set dummy render target array size to make sure that + // render targets are actually bound the first time + // SetRenderTargets() is called + m_pBoundRenderTargets.resize( 8 ); + } + + ~DeviceContextBase() + { + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DeviceContext, ObjectBase<BaseInterface> ) + + virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) = 0; + + virtual void ClearState() = 0; + + virtual void SetShaders( IShader **ppShaders, Uint32 NumShadersToSet ) + { + m_pBoundShaders.resize( NumShadersToSet ); + for( Uint32 i = 0; i < NumShadersToSet; ++i ) + m_pBoundShaders[i] = ppShaders[i]; +#ifdef DEBUG_CHECKS + { + Uint32 BoundShaders = 0; + for( auto sh = m_pBoundShaders.begin(); sh != m_pBoundShaders.end(); ++sh ) + { + auto ShaderType = (*sh)->GetDesc().ShaderType; + if( BoundShaders & ShaderType ) + { + LOG_ERROR_MESSAGE( "More than one shader of type ", GetShaderTypeLiteralName( ShaderType ), " is being set to the pipeline" ); + BoundShaders |= ShaderType; + } + } + } +#endif + } + + virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) + { + } + + // Body of the pure virtual function cannot be inlined + /// Caches the strong reference to the vertex description + virtual void SetVertexDescription( IVertexDescription *pVertexDesc ) = 0; + + /// Caches the strong reference to the index buffer + virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) = 0; + + /// If the new depth stencil parameters differ from the cached values, + /// updates the values and returns true. Otherwise returns false. + bool SetDepthStencilState( IDepthStencilState *pDSState, Uint32 StencilRef, Uint32 Dummy = 0); + + + /// If the new rasterizer state differs from the cached state, + /// updates the cached state and returns true. Otherwise returns false. + bool SetRasterizerState( IRasterizerState *pRS, Uint32 Dummy = 0 ); + + + /// If the new blend parameters differ from the cached values, + /// updates the cached values and returns true. Otherwise returns false. + bool SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask, Uint32 Dummy = 0 ); + + /// Caches the viewports + void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 &RTWidth, Uint32 &RTHeight ); + + /// Caches the scissor rects + void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 &RTWidth, Uint32 &RTHeight ); + + /// Caches the render target and depth stencil views. Returns true if any view is different + /// from the cached value and false otherwise. + bool SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil, Uint32 Dummy = 0 ); + + /// Sets the strong pointer to the swap chain + void SetSwapChain( ISwapChain *pSwapChain ) { m_pSwapChain = pSwapChain; } + + bool IsDefaultFBBound(){ return m_pBoundRenderTargets.size() == 0 && m_pBoundDepthStencil == nullptr; } + + void GetDepthStencilState(IDepthStencilState **ppDSS, Uint32 &StencilRef); + + void GetRasterizerState( IRasterizerState **ppRS ); + + void GetBlendState( IBlendState **ppBS, float* BlendFactors, Uint32& SamplesBlendMask ); + + void GetRenderTargets(Uint32 &NumRenderTargets, ITextureView **ppRTVs, ITextureView **ppDSV); + + /// Creates and binds default depth stencil, rasterizer & blend states + void CreateDefaultStates(); + + void GetShaders( IShader **ppShaders, Uint32 &NumShaders ); + + void GetViewports( Uint32 &NumViewports, Viewport *pViewports ); + +protected: + /// Returns the size of the currently bound render target + void GetRenderTargetSize( Uint32 &RTWidth, Uint32 &RTHeight ); + + /// Strong reference to the device. + RefCntAutoPtr<IRenderDevice> m_pDevice; + + /// Strong reference to the swap chain. Swap chain holds + /// weak reference to the immediate context. + RefCntAutoPtr<ISwapChain> m_pSwapChain; + + /// Vector of strong references to bound shaders + std::vector< RefCntAutoPtr<IShader> > m_pBoundShaders; + + /// Vertex streams. Every stream holds strong reference to the buffer + std::vector<VertexStreamInfo> m_VertexStreams; + + /// Strong reference to the bound vertex description object + RefCntAutoPtr<IVertexDescription> m_pVertexDesc; + + /// Strong reference to the bound index buffer + RefCntAutoPtr<IBuffer> m_pIndexBuffer; + + Uint32 m_IndexDataStartOffset; + + /// Strong references to the bound depth-stencil state + RefCntAutoPtr< IDepthStencilState > m_pDSState; + + /// Strong references to the bound rasterizer state + RefCntAutoPtr< IRasterizerState> m_pRasterizerState; + + /// Strong references to the bound blend state + RefCntAutoPtr< IBlendState> m_pBlendState; + + /// Current stencil reference value + Uint32 m_StencilRef; + + /// Curent blend factors + Float32 m_BlendFactors[4]; + + /// Current samples blend mask + Uint32 m_SamplesBlendMask; + + /// Current viewports + std::vector<Viewport> m_Viewports; + + /// Current scissor rects + std::vector<Rect> m_ScissorRects; + + /// Vector of strong references to bound render targets + std::vector< RefCntAutoPtr<ITextureView> > m_pBoundRenderTargets; + + /// Strong references to the bound depth stencil view + RefCntAutoPtr<ITextureView> m_pBoundDepthStencil; + +private: + RefCntAutoPtr<IDepthStencilState> m_pDefaultDSS; + RefCntAutoPtr<IRasterizerState> m_pDefaultRS; + RefCntAutoPtr<IBlendState> m_pDefaultBS; +}; + + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) +{ + if( StartSlot >= MaxBufferSlots ) + { + LOG_ERROR_MESSAGE( "Start vertex buffer slot ", StartSlot, " is out of allowed range [0, ", MaxBufferSlots-1, "]." ) + return; + } + + if( StartSlot + NumBuffersSet > MaxBufferSlots ) + { + LOG_ERROR_MESSAGE( "The range of vertex buffer slots being set [", StartSlot, ", ", StartSlot + NumBuffersSet - 1, "] is out of allowed range [0, ", MaxBufferSlots - 1, "]." ) + NumBuffersSet = MaxBufferSlots - StartSlot; + } + + if( Flags & SET_VERTEX_BUFFERS_FLAG_RESET ) + { + m_VertexStreams.clear(); + } + m_VertexStreams.resize( std::max(m_VertexStreams.size(), static_cast<size_t>(StartSlot + NumBuffersSet) ) ); + for( Uint32 Buff = 0; Buff < NumBuffersSet; ++Buff ) + { + auto &CurrStream = m_VertexStreams[StartSlot + Buff]; + CurrStream.pBuffer = RefCntAutoPtr<IBuffer>( ppBuffers ? ppBuffers[Buff] : nullptr ); + CurrStream.Stride = pStrides ? pStrides[Buff] : 0; + CurrStream.Offset = pOffsets ? pOffsets[Buff] : 0; +#ifdef DEBUG_CHECKS + if( CurrStream.pBuffer ) + { + const auto &BuffDesc = CurrStream.pBuffer->GetDesc(); + if( !(BuffDesc.BindFlags & BIND_VERTEX_BUFFER) ) + { + LOG_ERROR_MESSAGE( "Buffer \"", BuffDesc.Name ? BuffDesc.Name : "", "\" being bound as vertex buffer to slot ", Buff," was not created with BIND_VERTEX_BUFFER flag" ); + } + } +#endif + } + // Remove null buffers from the end of the array + while(m_VertexStreams.size() > 0 && !m_VertexStreams.back().pBuffer) + m_VertexStreams.pop_back(); +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: ClearState() +{ + UNSUPPORTED("This function is not implemented") + //m_VertexStreams.clear(); + //m_pIndexBuffer.Release(); + //m_IndexDataStartOffset = 0; +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: SetVertexDescription( IVertexDescription *pVertexDesc ) +{ + m_pVertexDesc = pVertexDesc; +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) +{ + m_pIndexBuffer = pIndexBuffer; + m_IndexDataStartOffset = ByteOffset; +#ifdef DEBUG_CHECKS + const auto &BuffDesc = m_pIndexBuffer->GetDesc(); + if( !(BuffDesc.BindFlags & BIND_INDEX_BUFFER) ) + { + LOG_ERROR_MESSAGE( "Buffer \"", BuffDesc.Name ? BuffDesc.Name : "", "\" being bound as index buffer was not created with BIND_INDEX_BUFFER flag" ); + } +#endif +} + + +/// \param [in] pDSState - pointer to the new depth-stencil state interface. +/// \param [in] StencilRef - new stencil reference value. +/// \param [in] Dummy - dummy argument required to make function signature distinct +/// from IDeviceContext::SetDepthStencilState(). This is required +/// because otherwise this overloaded function will only differ in +/// the return type which is not allowed. +/// \return +/// - True if either new depth stencil state or stencil reference value differs from +/// currently cached values. +/// - False otherwise. +/// +/// \remarks The method caches *strong reference* to the provided interface in m_pDSState. +template<typename BaseInterface> +bool DeviceContextBase<BaseInterface> :: SetDepthStencilState( IDepthStencilState *pDSState, Uint32 StencilRef, Uint32 Dummy ) +{ + // If null depth-stencil state is provided, bind default state + if( !pDSState ) + pDSState = m_pDefaultDSS; + + // Here m_pDSState is certainly a live object because we keep the + // strong reference. pDSState is also clearly live object, so we can + // safely compare pointers. + if( m_pDSState != pDSState || m_StencilRef != StencilRef ) + { + m_pDSState = pDSState; + m_StencilRef = StencilRef; + return true; + } + + return false; +} + +/// \param [in] pRS - pointer to the new rasterizer state interface. +/// \param [in] Dummy - dummy argument required to make function signature distinct +/// from IDeviceContext::SetRasterizerState(). This is required +/// because otherwise this overloaded function will only differ in +/// the return type which is not allowed. +/// \return +/// - True if the new rasterizer state differ from the cached state. +/// - False otherwise. +/// +/// \remarks The method caches *strong reference* to the provided interface in m_pRasterizerState. +template<typename BaseInterface> +bool DeviceContextBase<BaseInterface> :: SetRasterizerState( IRasterizerState *pRS, Uint32 Dummy ) +{ + // If null rasterizer state provided, bind default state + if( !pRS ) + pRS = m_pDefaultRS; + + // Here m_pRasterizerState is certainly a live object because we keep the + // strong reference. pRS is also clearly live object, so we can + // safely compare pointers. + if( m_pRasterizerState != pRS ) + { + m_pRasterizerState = pRS; + return true; + } + + return false; +} + + +/// \param [in] pBS - pointer to the new blend state interface. +/// \param [in] pBlendFactors - new blend factors. +/// \param [in] SampleMask - new sample mask. +/// \param [in] Dummy - dummy argument required to make function signature distinct +/// from IDeviceContext::SetBlendState(). This is required +/// because otherwise this overloaded function will only differ in +/// the return type which is not allowed. +/// \return +/// - True if either the new blend state, blend factors or sample mask value differs from +/// the currently cached values. +/// - False otherwise. +/// +/// \remarks The method caches *strong reference* to the provided interface in m_pBlendState. +template<typename BaseInterface> +bool DeviceContextBase<BaseInterface> :: SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask, Uint32 Dummy ) +{ + // If null blend state provided, bind default state + if( !pBS ) + pBS = m_pDefaultBS; + + static const float DefaultBlendFactors[4] = { 1, 1, 1, 1 }; + if( pBlendFactors == nullptr ) + pBlendFactors = DefaultBlendFactors; + + // Here m_pBlendState is certainly a live object because we keep the + // strong reference. pBS is also clearly live object, so we can + // safely compare pointers. + if( m_pBlendState != pBS || + m_BlendFactors[0] != pBlendFactors[0] || + m_BlendFactors[1] != pBlendFactors[1] || + m_BlendFactors[2] != pBlendFactors[2] || + m_BlendFactors[3] != pBlendFactors[3] || + m_SamplesBlendMask != SampleMask ) + { + m_pBlendState = pBS; + m_SamplesBlendMask = SampleMask; + for( int i = 0; i < 4; ++i ) + m_BlendFactors[i] = pBlendFactors[i]; + + return true; + } + + return false; +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: GetDepthStencilState(IDepthStencilState **ppDSS, Uint32 &StencilRef) +{ + VERIFY( ppDSS != nullptr, "Null pointer provided null" ); + VERIFY( *ppDSS == nullptr, "Memory address contains a pointer to a non-null depth-stencil state" ); + VERIFY( m_pDSState, "No depth-stencil state is bound. At least default state must always be bound. Did you forget to call CreateDefaultStates()?" ); + m_pDSState->QueryInterface( IID_DepthStencilState, reinterpret_cast<IObject**>( ppDSS ) ); + StencilRef = m_StencilRef; +}; + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: GetRasterizerState(IRasterizerState **ppRS ) +{ + VERIFY( ppRS != nullptr, "Null pointer provided null" ); + VERIFY( *ppRS == nullptr, "Memory address contains a pointer to a non-null rasterizer state" ); + VERIFY( m_pRasterizerState, "No rasterizer state is bound. At least default state must always be bound. Did you forget to call CreateDefaultStates()?" ); + m_pRasterizerState->QueryInterface( IID_RasterizerState, reinterpret_cast<IObject**>( ppRS ) ); +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: GetBlendState( IBlendState **ppBS, float* BlendFactors, Uint32& SamplesBlendMask ) +{ + VERIFY( ppBS != nullptr, "Null pointer provided null" ); + VERIFY( *ppBS == nullptr, "Memory address contains a pointer to a non-null blend state" ); + VERIFY( m_pBlendState, "No blend state is bound. At least default state must always be bound. Did you forget to call CreateDefaultStates()?" ); + m_pBlendState->QueryInterface( IID_BlendState, reinterpret_cast<IObject**>( ppBS ) ); + for( Uint32 f = 0; f < 4; ++f ) + BlendFactors[f] = m_BlendFactors[f]; + SamplesBlendMask = m_SamplesBlendMask; +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: GetRenderTargetSize( Uint32 &RTWidth, Uint32 &RTHeight ) +{ + RTWidth = 0; + RTHeight = 0; + // First, try to find non-null render target + for( Uint32 rt = 0; rt < m_pBoundRenderTargets.size(); ++rt ) + if( auto *pRTView = m_pBoundRenderTargets[rt].RawPtr() ) + { + // Use render target size as viewport size + auto *pTex = pRTView->GetTexture(); + auto MipLevel = pRTView->GetDesc().MostDetailedMip; + const auto &TexDesc = pTex->GetDesc(); + RTWidth = TexDesc.Width >> MipLevel; + RTHeight = TexDesc.Height >> MipLevel; + VERIFY( RTWidth > 0 && RTHeight > 0, "RT dimension is zero" ); + break; + } + + // If render target was not found, check depth stencil + if( RTWidth == 0 || RTHeight == 0 ) + { + auto *pDSView = m_pBoundDepthStencil.RawPtr(); + if( pDSView != nullptr ) + { + // Use depth stencil size + auto *pTex = pDSView->GetTexture(); + const auto &TexDesc = pTex->GetDesc(); + RTWidth = TexDesc.Width; + RTHeight = TexDesc.Height; + } + } + + // Finally, if no render targets and depth stencil are bound, + // use default RT size + if( RTWidth == 0 || RTHeight == 0 ) + { + const auto &SwapChainDesc = m_pSwapChain->GetDesc(); + RTWidth = SwapChainDesc.Width; + RTHeight = SwapChainDesc.Height; + } +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 &RTWidth, Uint32 &RTHeight ) +{ + if( RTWidth == 0 || RTHeight == 0 ) + { + GetRenderTargetSize( RTWidth, RTHeight ); + } + + m_Viewports.resize(NumViewports); + Viewport DefaultVP( 0, 0, static_cast<float>(RTWidth), static_cast<float>(RTHeight) ); + // If no viewports are specified, use default viewport + if( NumViewports == 1 && pViewports == nullptr ) + { + pViewports = &DefaultVP; + } + + for( Uint32 vp = 0; vp < NumViewports; ++vp ) + { + m_Viewports[vp] = pViewports[vp]; + VERIFY( m_Viewports[vp].Width >= 0, "Incorrect viewport width (", m_Viewports[vp].Width, ")" ); + VERIFY( m_Viewports[vp].Height >= 0 , "Incorrect viewport height (", m_Viewports[vp].Height, ")" ); + VERIFY( m_Viewports[vp].MaxDepth >= m_Viewports[vp].MinDepth, "Incorrect viewport depth range [", m_Viewports[vp].MinDepth, ", ", m_Viewports[vp].MaxDepth, "]" ); + } +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: GetViewports( Uint32 &NumViewports, Viewport *pViewports ) +{ + NumViewports = static_cast<Uint32>( m_Viewports.size() ); + if( pViewports ) + { + for( Uint32 vp = 0; vp < m_Viewports.size(); ++vp ) + pViewports[vp] = m_Viewports[vp]; + } +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 &RTWidth, Uint32 &RTHeight ) +{ + if( RTWidth == 0 || RTHeight == 0 ) + { + GetRenderTargetSize( RTWidth, RTHeight ); + } + + m_ScissorRects.resize( NumRects ); + for( Uint32 sr = 0; sr < NumRects; ++sr ) + { + m_ScissorRects[sr] = pRects[sr]; + VERIFY( m_ScissorRects[sr].left <= m_ScissorRects[sr].right, "Incorrect horizontal bounds for a scissor rect [", m_ScissorRects[sr].left, ", ", m_ScissorRects[sr].right, ")" ); + VERIFY( m_ScissorRects[sr].top <= m_ScissorRects[sr].bottom, "Incorrect vertical bounds for a scissor rect [", m_ScissorRects[sr].top, ", ", m_ScissorRects[sr].bottom, ")" ); + } +} + +template<typename BaseInterface> +bool DeviceContextBase<BaseInterface> :: SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil, Uint32 Dummy ) +{ + bool bBindRenderTargets = false; + if( NumRenderTargets != m_pBoundRenderTargets.size() ) + { + bBindRenderTargets = true; + m_pBoundRenderTargets.resize(NumRenderTargets); + } + + for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + { + auto *pRTView = ppRenderTargets[rt]; +#ifdef _DEBUG + if( pRTView ) + { + const auto &ViewDesc = pRTView->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Texture view object named \"", ViewDesc.Name ? ViewDesc.Name : "", "\" has incorrect view type (", GetTexViewTypeLiteralName(ViewDesc.ViewType), "). Render target view is expected" ); + } +#endif + // Here both views a certainly live object, since we store + // strong references to all bound render targets. So we + // can safely compare pointers. + if( m_pBoundRenderTargets[rt] != pRTView ) + { + m_pBoundRenderTargets[rt] = pRTView; + bBindRenderTargets = true; + } + } + +#ifdef _DEBUG + if( pDepthStencil ) + { + const auto &ViewDesc = pDepthStencil->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Texture view object named \"", ViewDesc.Name ? ViewDesc.Name : "", "\" has incorrect view type (", GetTexViewTypeLiteralName(ViewDesc.ViewType), "). Depth stencil view is expected" ); + } +#endif + + if( m_pBoundDepthStencil != pDepthStencil) + { + m_pBoundDepthStencil = pDepthStencil; + bBindRenderTargets = true; + } + + return bBindRenderTargets; +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: GetRenderTargets( Uint32 &NumRenderTargets, ITextureView **ppRTVs, ITextureView **ppDSV ) +{ + NumRenderTargets = static_cast<Uint32>( m_pBoundRenderTargets.size() ); + + if( ppRTVs ) + { + for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + { + VERIFY( ppRTVs[rt] == nullptr, "Non-null pointer found in RTV array element #", rt ); + auto pBoundRTV = m_pBoundRenderTargets[rt]; + if( pBoundRTV ) + pBoundRTV->QueryInterface( IID_TextureView, reinterpret_cast<IObject**>(ppRTVs + rt) ); + else + ppRTVs[rt] = nullptr; + } + for( Uint32 rt = NumRenderTargets; rt < MaxRenderTargets; ++rt ) + { + VERIFY( ppRTVs[rt] == nullptr, "Non-null pointer found in RTV array element #", rt ); + ppRTVs[rt] = nullptr; + } + } + + if( ppDSV ) + { + VERIFY( *ppDSV == nullptr, "Non-null DSV pointer found" ); + if( m_pBoundDepthStencil ) + m_pBoundDepthStencil->QueryInterface( IID_TextureView, reinterpret_cast<IObject**>(ppDSV) ); + else + *ppDSV = nullptr; + } +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: CreateDefaultStates() +{ + DepthStencilStateDesc DefaultDSSDesc; + DefaultDSSDesc.Name = "Default depth stencil state"; + m_pDevice->CreateDepthStencilState( DefaultDSSDesc, &m_pDefaultDSS ); + + RasterizerStateDesc DefaultRSDesc; + DefaultRSDesc.Name = "Default rasterizer state"; + m_pDevice->CreateRasterizerState( DefaultRSDesc, &m_pDefaultRS ); + + BlendStateDesc DefaultBlendState; + DefaultBlendState.Name = "Default blend state"; + m_pDevice->CreateBlendState( DefaultBlendState, &m_pDefaultBS ); + + SetDepthStencilState( m_pDefaultDSS, 0 ); + SetRasterizerState( m_pDefaultRS ); + float BlendFactors[4] = { 1, 1, 1, 1 }; + SetBlendState( m_pDefaultBS, BlendFactors, 0xFFFFFFFF ); +} + +template<typename BaseInterface> +void DeviceContextBase<BaseInterface> :: GetShaders( IShader **ppShaders, Uint32 &NumShaders ) +{ + NumShaders = static_cast<Uint32>( m_pBoundShaders.size() ); + if( ppShaders == nullptr ) + return; + for( Uint32 s = 0; s < NumShaders; ++s ) + { + VERIFY( ppShaders[s] == nullptr, "Non-null pointer found in shader array element #", s ); + if( auto pBoundShader = m_pBoundShaders[s] ) + pBoundShader->QueryInterface( IID_Shader, reinterpret_cast<IObject**>( ppShaders + s ) ); + else + ppShaders[s] = nullptr; + } +} + +} diff --git a/Graphics/GraphicsEngine/include/DeviceObjectBase.h b/Graphics/GraphicsEngine/include/DeviceObjectBase.h new file mode 100644 index 00000000..f96b6d7c --- /dev/null +++ b/Graphics/GraphicsEngine/include/DeviceObjectBase.h @@ -0,0 +1,117 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::DeviceObjectBase template class + +#include "ObjectBase.h" +#include "UniqueIdentifier.h" + +namespace Diligent +{ + +template<typename BaseInterface> +class RenderDeviceBase; + +/// Template class implementing base functionality for a device object +template<class BaseInterface, typename ObjectDescType> +class DeviceObjectBase : public ObjectBase<BaseInterface> +{ +public: + + /// \param pDevice - pointer to the render device. + /// \param ObjDesc - object description. + /// \param pOwner - owner object. + /// \param bIsDeviceInternal - flag indicating if the object is an internal device object + /// and must not keep a strong reference to the device. + DeviceObjectBase( class IRenderDevice *pDevice, + const ObjectDescType &ObjDesc, + IObject *pOwner = nullptr, + bool bIsDeviceInternal = false) : + ObjectBase<BaseInterface>(pOwner), + m_pDevice( pDevice ), + // Do not keep strong reference to the device if the object is an internal device object + m_spDevice( bIsDeviceInternal ? nullptr : pDevice ), + m_ObjectNameCopy(ObjDesc.Name ? ObjDesc.Name : ""), + m_Desc( ObjDesc ) + { + m_Desc.Name = m_ObjectNameCopy.c_str(); + + // !!!WARNING!!! + // We cannot add resource to the hash table from here, because the object + // has not been completely created yet and the reference counters object + // is not initialized! + //m_pDevice->AddResourceToHash( this ); - ERROR! + } + + virtual ~DeviceObjectBase() + { + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DeviceObject, ObjectBase<BaseInterface> ) + + virtual const ObjectDescType& GetDesc()const override + { + return m_Desc; + } + + /// Returns unique identifier + UniqueIdentifier GetUniqueID()const + { + /// \note + /// This unique ID is used to unambiguously identify device object for + /// tracking purposes. + /// Niether GL handle nor pointer could be safely used for this purpose + /// as both GL reuses released handles and the OS reuses released pointers + return m_UniqueID.GetID(); + } + +protected: + + IRenderDevice *GetDevice(){return m_pDevice;} + + /// Copy of a device object name + const String m_ObjectNameCopy; + + /// Object description + ObjectDescType m_Desc; + + // Template argument is only used to separate counters for + // different groups of objects + UniqueIdHelper<BaseInterface> m_UniqueID; + +private: + /// Pointer to the device + IRenderDevice *m_pDevice; + /// Strong reference to the device + RefCntAutoPtr<IRenderDevice> m_spDevice; + + DeviceObjectBase( const DeviceObjectBase& ); + DeviceObjectBase( DeviceObjectBase&& ); + const DeviceObjectBase& operator = ( const DeviceObjectBase& ); + const DeviceObjectBase& operator = ( DeviceObjectBase&& ); +}; + +} diff --git a/Graphics/GraphicsEngine/include/RasterizerStateBase.h b/Graphics/GraphicsEngine/include/RasterizerStateBase.h new file mode 100644 index 00000000..a3c90275 --- /dev/null +++ b/Graphics/GraphicsEngine/include/RasterizerStateBase.h @@ -0,0 +1,69 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::RasterizerStateBase template class + +#include "RasterizerState.h" +#include "DeviceObjectBase.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a rasterizer object. + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IRasterizerStateD3D11 or Diligent::IRasterizerStateGL). +/// \tparam RenderDeviceBaseInterface - base interface for the render device +/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceGL, +/// or Diligent::IRenderDeviceGLES). +template<class BaseInterface = IRasterizerState, class RenderDeviceBaseInterface = IRenderDevice> +class RasterizerStateBase : public DeviceObjectBase<BaseInterface, RasterizerStateDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, RasterizerStateDesc> TDeviceObjectBase; + typedef RenderDeviceBase < RenderDeviceBaseInterface > TRenderDeviceBase; + + /// \param pDevice - pointer to the device. + /// \param RSDesc - rasterizer state description. + /// \param bIsDeviceInternal - flag indicating if the state is an internal device object and + /// must not keep a strong reference to the device. + RasterizerStateBase( IRenderDevice *pDevice, const RasterizerStateDesc& RSDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pDevice, RSDesc, nullptr, bIsDeviceInternal ) + { + } + + ~RasterizerStateBase() + { + /// \note Destructor cannot directly remove the object from the registry as this may cause a + /// deadlock. See BlendStateBase::~BlendStateBase() for details. + auto &RasterizerStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetRSRegistry(); + RasterizerStateRegistry.ReportDeletedObject(); + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_RasterizerState, TDeviceObjectBase ) +}; + +} diff --git a/Graphics/GraphicsEngine/include/RenderDeviceBase.h b/Graphics/GraphicsEngine/include/RenderDeviceBase.h new file mode 100644 index 00000000..97103f23 --- /dev/null +++ b/Graphics/GraphicsEngine/include/RenderDeviceBase.h @@ -0,0 +1,399 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::RenderDeviceBase template class and related structures + +#include "RenderDevice.h" +#include "DeviceObjectBase.h" +#include "Defines.h" +#include "ResourceMappingImpl.h" +#include "StateObjectsRegistry.h" +#include "HashUtils.h" +#include "ObjectBase.h" +#include "DeviceContext.h" +#include "SwapChain.h" +#include "GraphicsUtilities.h" + +using Diligent::RefCntAutoPtr; +using Diligent::RefCntWeakPtr; + +namespace std +{ + /// Hash function specialization for Diligent::SamplerDesc structure. + template<> + struct hash<Diligent::SamplerDesc> + { + size_t operator()( const Diligent::SamplerDesc &SamDesc ) const + { + // Sampler name is ignored in comparison operator + // and should not be hashed + return Diligent::ComputeHash( // SamDesc.Name, + static_cast<int>(SamDesc.MinFilter), + static_cast<int>(SamDesc.MagFilter), + static_cast<int>(SamDesc.MipFilter), + static_cast<int>(SamDesc.AddressU), + static_cast<int>(SamDesc.AddressV), + static_cast<int>(SamDesc.AddressW), + SamDesc.MipLODBias, + SamDesc.MaxAnisotropy, + static_cast<int>(SamDesc.ComparisonFunc), + SamDesc.BorderColor[0], + SamDesc.BorderColor[1], + SamDesc.BorderColor[2], + SamDesc.BorderColor[3], + SamDesc.MinLOD, SamDesc.MaxLOD ); + } + }; + + /// Hash function specialization for Diligent::StencilOpDesc structure. + template<> + struct hash<Diligent::StencilOpDesc> + { + size_t operator()( const Diligent::StencilOpDesc &StOpDesc ) const + { + return Diligent::ComputeHash( static_cast<int>( StOpDesc.StencilFailOp ), + static_cast<int>( StOpDesc.StencilDepthFailOp ), + static_cast<int>( StOpDesc.StencilPassOp ), + static_cast<int>( StOpDesc.StencilFunc ) ); + } + }; + + /// Hash function specialization for Diligent::DepthStencilStateDesc structure. + template<> + struct hash<Diligent::DepthStencilStateDesc> + { + size_t operator()( const Diligent::DepthStencilStateDesc &DSSDesc ) const + { + // Depth-stencil state name is ignored in comparison operator + // and should not be hashed + return Diligent::ComputeHash( // DSSDesc.Name, + DSSDesc.DepthEnable, + DSSDesc.DepthWriteEnable, + static_cast<int>(DSSDesc.DepthFunc), + DSSDesc.StencilEnable, + DSSDesc.StencilReadMask, + DSSDesc.StencilWriteMask, + DSSDesc.FrontFace, + DSSDesc.BackFace ); + } + }; + + /// Hash function specialization for Diligent::RasterizerStateDesc structure. + template<> + struct hash<Diligent::RasterizerStateDesc> + { + size_t operator()( const Diligent::RasterizerStateDesc &RSDesc ) const + { + // Rasterizer state name is ignored in comparison operator + // and should not be hashed + return Diligent::ComputeHash( // RSDesc.Name, + static_cast<int>( RSDesc.FillMode ), + static_cast<int>( RSDesc.CullMode ), + RSDesc.FrontCounterClockwise, + RSDesc.DepthBias, + RSDesc.DepthBiasClamp, + RSDesc.SlopeScaledDepthBias, + RSDesc.DepthClipEnable, + RSDesc.ScissorEnable, + RSDesc.AntialiasedLineEnable ); + } + }; + + /// Hash function specialization for Diligent::BlendStateDesc structure. + template<> + struct hash<Diligent::BlendStateDesc> + { + size_t operator()( const Diligent::BlendStateDesc &BSDesc ) const + { + std::size_t Seed = 0; + for( int i = 0; i < Diligent::BlendStateDesc::MaxRenderTargets; ++i ) + { + const auto& rt = BSDesc.RenderTargets[i]; + Diligent::HashCombine( Seed, + rt.BlendEnable, + static_cast<int>( rt.SrcBlend ), + static_cast<int>( rt.DestBlend ), + static_cast<int>( rt.BlendOp ), + static_cast<int>( rt.SrcBlendAlpha ), + static_cast<int>( rt.DestBlendAlpha ), + static_cast<int>( rt.BlendOpAlpha ), + rt.RenderTargetWriteMask ); + } + Diligent::HashCombine( Seed, + // Blend state name is ignored in comparison operator + // and should not be hashed + // BSDesc.Name, + BSDesc.AlphaToCoverageEnable, + BSDesc.IndependentBlendEnable ); + return Seed; + } + }; + + + /// Hash function specialization for Diligent::BlendStateDesc structure. + template<> + struct hash<Diligent::TextureViewDesc> + { + size_t operator()( const Diligent::TextureViewDesc &TexViewDesc ) const + { + std::size_t Seed = 0; + Diligent::HashCombine( Seed, + static_cast<Diligent::Int32>(TexViewDesc.ViewType), + static_cast<Diligent::Int32>(TexViewDesc.TextureType), + static_cast<Diligent::Int32>(TexViewDesc.Format), + TexViewDesc.MostDetailedMip, + TexViewDesc.NumMipLevels, + TexViewDesc.FirstArraySlice, + TexViewDesc.NumArraySlices, + TexViewDesc.AccessFlags ); + return Seed; + } + }; +} + +namespace Diligent +{ + +/// Base implementation of a render device + +/// \warning +/// Render device must *NOT* hold strong references to any +/// object it creates to avoid circular dependencies. +/// Device context, swap chain and all object the device creates +/// keep strong reference to the device. +/// Device only holds weak reference to immediate context. +template<typename BaseInterface = IRenderDevice> +class RenderDeviceBase : public ObjectBase<BaseInterface> +{ +public: + RenderDeviceBase() : + m_TextureFormatsInfo( TEX_FORMAT_NUM_FORMATS ), + m_TexFmtInfoInitFlags( TEX_FORMAT_NUM_FORMATS ), + m_SamplersRegistry("sampler"), + m_DSSRegistry("ds state"), + m_RSRegistry("rasterizer state"), + m_BSRegistry("blend state") + { + // Initialize texture format info + for( Uint32 Fmt = TEX_FORMAT_UNKNOWN; Fmt < TEX_FORMAT_NUM_FORMATS; ++Fmt ) + static_cast<TextureFormatAttribs&>(m_TextureFormatsInfo[Fmt]) = GetTextureFormatAttribs( static_cast<TEXTURE_FORMAT>(Fmt) ); + + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff471325(v=vs.85).aspx + std::vector<TEXTURE_FORMAT> FilterableFormats = + { + TEX_FORMAT_RGBA32_FLOAT, // OpenGL ES3.1 does not require this format to be filterable + TEX_FORMAT_RGBA16_FLOAT, + TEX_FORMAT_RGBA16_UNORM, + TEX_FORMAT_RGBA16_SNORM, + TEX_FORMAT_RG32_FLOAT, // OpenGL ES3.1 does not require this format to be filterable + TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS, + //TEX_FORMAT_R10G10B10A2_UNORM, + TEX_FORMAT_R11G11B10_FLOAT, + TEX_FORMAT_RGBA8_UNORM, + TEX_FORMAT_RGBA8_UNORM_SRGB, + TEX_FORMAT_RGBA8_SNORM, + TEX_FORMAT_RG16_FLOAT, + TEX_FORMAT_RG16_UNORM, + TEX_FORMAT_RG16_SNORM, + TEX_FORMAT_R32_FLOAT, // OpenGL ES3.1 does not require this format to be filterable + TEX_FORMAT_R24_UNORM_X8_TYPELESS, + TEX_FORMAT_RG8_UNORM, + TEX_FORMAT_RG8_SNORM, + TEX_FORMAT_R16_FLOAT, + TEX_FORMAT_R16_UNORM, + TEX_FORMAT_R16_SNORM, + TEX_FORMAT_R8_UNORM, + TEX_FORMAT_R8_SNORM, + TEX_FORMAT_A8_UNORM, + TEX_FORMAT_RGB9E5_SHAREDEXP, + TEX_FORMAT_RG8_B8G8_UNORM, + TEX_FORMAT_G8R8_G8B8_UNORM, + TEX_FORMAT_BC1_UNORM, + TEX_FORMAT_BC1_UNORM_SRGB, + TEX_FORMAT_BC2_UNORM, + TEX_FORMAT_BC2_UNORM_SRGB, + TEX_FORMAT_BC3_UNORM, + TEX_FORMAT_BC3_UNORM_SRGB, + TEX_FORMAT_BC4_UNORM, + TEX_FORMAT_BC4_SNORM, + TEX_FORMAT_BC5_UNORM, + TEX_FORMAT_BC5_SNORM, + TEX_FORMAT_B5G6R5_UNORM + }; + for( auto fmt = FilterableFormats.begin(); fmt != FilterableFormats.end(); ++fmt ) + m_TextureFormatsInfo[ *fmt ].Filterable = true; + } + + ~RenderDeviceBase() + { + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_RenderDevice, ObjectBase<BaseInterface> ) + + virtual void CreateResourceMapping( const ResourceMappingDesc &MappingDesc, IResourceMapping **ppMapping ); + + virtual const DeviceCaps& GetDeviceCaps()const + { + return m_DeviceCaps; + } + + virtual const TextureFormatInfo &GetTextureFormatInfo(TEXTURE_FORMAT TexFormat) + { + VERIFY( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS, "Texture format out of range" ); + const auto& TexFmtInfo = m_TextureFormatsInfo[TexFormat]; + VERIFY( TexFmtInfo.Format == TexFormat, "Sanity check failed" ); + return TexFmtInfo; + } + + virtual const TextureFormatInfoExt &GetTextureFormatInfoExt( TEXTURE_FORMAT TexFormat ) + { + VERIFY( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS, "Texture format out of range" ); + const auto& TexFmtInfo = m_TextureFormatsInfo[TexFormat]; + VERIFY( TexFmtInfo.Format == TexFormat, "Sanity check failed" ); + if( !m_TexFmtInfoInitFlags[TexFormat] ) + { + if( TexFmtInfo.Supported ) + TestTextureFormat(TexFormat); + m_TexFmtInfoInitFlags[TexFormat] = true; + } + return TexFmtInfo; + } + + void OnCreateDeviceObject( IDeviceObject *pNewObject ) + { + } + + StateObjectsRegistry<SamplerDesc> &GetSamplerRegistry(){ return m_SamplersRegistry; } + StateObjectsRegistry<DepthStencilStateDesc> &GetDSStateRegistry(){ return m_DSSRegistry; } + StateObjectsRegistry<RasterizerStateDesc> &GetRSRegistry() { return m_RSRegistry; } + StateObjectsRegistry<BlendStateDesc> &GetBSRegistry() { return m_BSRegistry; } + + /// Set weak reference to the immediate context + void SetImmediateContext(IDeviceContext *pImmediateContext) + { + VERIFY( m_wpImmediateContext.Lock() == nullptr, "Immediate context has already been set" ); + m_wpImmediateContext = pImmediateContext; + } + + RefCntAutoPtr<IDeviceContext> GetImmediateContext(){ return m_wpImmediateContext.Lock(); } + +protected: + + virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) = 0; + + /// Helper template function to facilitate device object creation + template<typename TObjectType, typename TObjectDescType, typename TObjectConstructor> + void CreateDeviceObject( const Char *ObjectTypeName, const TObjectDescType &Desc, TObjectType **ppObject, TObjectConstructor ConstructObject ); + + DeviceCaps m_DeviceCaps; + + // All state object registries hold raw pointers. + // This is safe because every object unregisters itself + // when it is deleted. + StateObjectsRegistry<SamplerDesc> m_SamplersRegistry; ///< Sampler state registry + StateObjectsRegistry<DepthStencilStateDesc> m_DSSRegistry;///< Depth-stencil state registry + StateObjectsRegistry<RasterizerStateDesc> m_RSRegistry; ///< Rasterizer state registry + StateObjectsRegistry<BlendStateDesc> m_BSRegistry; ///< Blend state registry + std::vector<TextureFormatInfoExt> m_TextureFormatsInfo; + std::vector<bool> m_TexFmtInfoInitFlags; + + /// Weak reference to the immediate context. Immediate context holds strong reference + /// to the device, so we must use weak reference to avoid circular dependencies. + Diligent::RefCntWeakPtr<IDeviceContext> m_wpImmediateContext; +}; + + +template<typename BaseInterface> +void RenderDeviceBase<BaseInterface>::CreateResourceMapping( const ResourceMappingDesc &MappingDesc, IResourceMapping **ppMapping ) +{ + VERIFY( ppMapping != nullptr, "Null pointer provided" ); + if( ppMapping == nullptr ) + return; + VERIFY( *ppMapping == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + + auto *pResourceMapping( new ResourceMappingImpl() ); + pResourceMapping->QueryInterface( IID_ResourceMapping, reinterpret_cast<IObject**>(ppMapping) ); + if( MappingDesc.pEntries ) + { + for( auto *pEntry = MappingDesc.pEntries; pEntry->Name && pEntry->pObject; ++pEntry ) + { + (*ppMapping)->AddResource( pEntry->Name, pEntry->pObject, true ); + } + } +} + + +/// \tparam TObjectType - type of the object being created (IBuffer, ITexture, IBlendState, etc.) +/// \tparam TObjectDescType - type of the object description structure (BufferDesc, TextureDesc, BlendStateDesc, etc.) +/// \tparam TObjectConstructor - type of the function that constructs the object +/// \param ObjectTypeName - string name of the object type ("buffer", "texture", etc.) +/// \param Desc - object description +/// \param ppObject - memory address where the pointer to the created object will be stored +/// \param ConstructObject - function that constructs the object +template<typename BaseInterface> +template<typename TObjectType, typename TObjectDescType, typename TObjectConstructor> +void RenderDeviceBase<BaseInterface> :: CreateDeviceObject( const Char *ObjectTypeName, const TObjectDescType &Desc, TObjectType **ppObject, TObjectConstructor ConstructObject ) +{ + VERIFY( ppObject != nullptr, "Null pointer provided" ); + if(!ppObject) + return; + + VERIFY( *ppObject == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + // Do not release *ppObject here! + // Should this happen, RefCntAutoPtr<> will take care of this! + //if( *ppObject ) + //{ + // (*ppObject)->Release(); + // *ppObject = nullptr; + //} + + *ppObject = nullptr; + + try + { + ConstructObject(); + } + catch( const std::runtime_error & ) + { + VERIFY( *ppObject == nullptr, "Object was created despite error" ); + if( *ppObject ) + { + (*ppObject)->Release(); + *ppObject = nullptr; + } + auto ObjectDescString = GetObjectDescString( Desc ); + if( ObjectDescString.length() ) + { + LOG_ERROR( "Failed to create ", ObjectTypeName, " object \"", Desc.Name ? Desc.Name : "", "\"\n", ObjectDescString ) + } + else + { + LOG_ERROR( "Failed to create ", ObjectTypeName, " object \"", Desc.Name ? Desc.Name : "", "\"" ) + } + } +} + +} diff --git a/Graphics/GraphicsEngine/include/ResourceMappingImpl.h b/Graphics/GraphicsEngine/include/ResourceMappingImpl.h new file mode 100644 index 00000000..6d412485 --- /dev/null +++ b/Graphics/GraphicsEngine/include/ResourceMappingImpl.h @@ -0,0 +1,58 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of the Diligent::ResourceMappingImpl class + +#include "ResourceMapping.h" +#include "ObjectBase.h" +#include <unordered_map> +#include "HashUtils.h" + +namespace Diligent +{ + /// Implementation of the resource mapping + class ResourceMappingImpl : public ObjectBase<IResourceMapping> + { + public: + ~ResourceMappingImpl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual void AddResource( const Char *Name, IDeviceObject *pObject, bool bIsUnique ); + virtual void RemoveResource( IDeviceObject *pObject ); + virtual void RemoveResourceByName( const Char *Name ); + + /// Finds resource in the mapping. If no resource is found, nullptr is returned + virtual void GetResource( const Char *Name, IDeviceObject **ppResource ); + virtual size_t GetSize(); + + private: + ThreadingTools::LockHelper Lock(); + + ThreadingTools::LockFlag m_LockFlag; + std::unordered_map< Diligent::HashMapStringKey, Diligent::RefCntAutoPtr<IDeviceObject> > m_HashTable; + }; +} diff --git a/Graphics/GraphicsEngine/include/SamplerBase.h b/Graphics/GraphicsEngine/include/SamplerBase.h new file mode 100644 index 00000000..de8ff566 --- /dev/null +++ b/Graphics/GraphicsEngine/include/SamplerBase.h @@ -0,0 +1,69 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::SamplerBase template class + +#include "Sampler.h" +#include "DeviceObjectBase.h" +#include "RenderDeviceBase.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a sampler object. + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::ISamplerD3D11 or Diligent::ISamplerGL). +/// \tparam RenderDeviceBaseInterface - base interface for the render device +/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceGL, +/// or Diligent::IRenderDeviceGLES). +template<class BaseInterface = ISampler, class RenderDeviceBaseInterface = IRenderDevice> +class SamplerBase : public DeviceObjectBase<BaseInterface, SamplerDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, SamplerDesc> TDeviceObjectBase; + typedef RenderDeviceBase<RenderDeviceBaseInterface> TRenderDeviceBase; + + /// \param pDevice - pointer to the device. + /// \param SamDesc - sampler description. + /// \param bIsDeviceInternal - flag indicating if the sampler is an internal device object and + /// must not keep a strong reference to the device. + SamplerBase( IRenderDevice *pDevice, const SamplerDesc& SamDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pDevice, SamDesc, nullptr, bIsDeviceInternal ) + {} + + ~SamplerBase() + { + /// \note Destructor cannot directly remove the object from the registry as this may cause a + /// deadlock. See BlendStateBase::~BlendStateBase() for details. + auto &SamplerRegistry = static_cast<TRenderDeviceBase *>(this->GetDevice())->GetSamplerRegistry(); + SamplerRegistry.ReportDeletedObject(); + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_Sampler, TDeviceObjectBase ) +}; + +} diff --git a/Graphics/GraphicsEngine/include/ShaderBase.h b/Graphics/GraphicsEngine/include/ShaderBase.h new file mode 100644 index 00000000..b2f89341 --- /dev/null +++ b/Graphics/GraphicsEngine/include/ShaderBase.h @@ -0,0 +1,92 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::ShaderBase template class + +#include "Shader.h" +#include "DeviceObjectBase.h" + +namespace Diligent +{ + +/// Base implementation of a shader variable +struct ShaderVariableBase : public ObjectBase<IShaderVariable> +{ + ShaderVariableBase(IShader *pShader) : + // Shader variables are always created as part of the shader, + // so we must provide owner pointer to the base class constructor + ObjectBase<IShaderVariable>(pShader), + m_pShader(pShader) + {} + + virtual IShader* GetShader()override + { + return m_pShader; + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_ShaderVariable, ObjectBase<IShaderVariable> ) + +protected: + IShader *m_pShader; +}; + +/// Implementation of a dummy shader variable that silently ignores all operations +struct DummyShaderVariable : ShaderVariableBase +{ + DummyShaderVariable(IShader *pShader) : + ShaderVariableBase(pShader) + {} + + virtual void Set( IDeviceObject *pObject )override + { + // Ignore operation + // Probably output warning + } +}; + +/// Template class implementing base functionality for a shader object +template<class BaseInterface = IShader, class RenderDeviceBaseInterface = IRenderDevice> +class ShaderBase : public DeviceObjectBase<BaseInterface, ShaderDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, ShaderDesc> TDeviceObjectBase; + + /// \param pDevice - pointer to the device. + /// \param ShdrDesc - shader description. + /// \param bIsDeviceInternal - flag indicating if the shader is an internal device object and + /// must not keep a strong reference to the device. + ShaderBase( IRenderDevice *pDevice, const ShaderDesc& ShdrDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pDevice, ShdrDesc, nullptr, bIsDeviceInternal ), + m_DummyShaderVar(this) + {} + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_Shader, TDeviceObjectBase ) + +protected: + DummyShaderVariable m_DummyShaderVar; ///< Dummy shader variable +}; + +} diff --git a/Graphics/GraphicsEngine/include/StateObjectsRegistry.h b/Graphics/GraphicsEngine/include/StateObjectsRegistry.h new file mode 100644 index 00000000..e26d1183 --- /dev/null +++ b/Graphics/GraphicsEngine/include/StateObjectsRegistry.h @@ -0,0 +1,204 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::StateObjectsRegistry template class + +#include "DeviceObject.h" +#include <unordered_map> + +namespace Diligent +{ + /// Template class implementing state object registry + + /// \tparam ResourceDescType - type of the resource description. The type must have + /// operator== and a hash function defined. + /// + /// \remarks + /// The following strategies do not work: + /// - To store raw pointers and remove the object from the registry in the + /// object's destructor. In this case other thread may obtain a reference + /// to the object while it is being deleted. This scenario is possible if one thread + /// has just entered the destructor, but other is executing Find() and entered + /// the protection section. + /// - Strong pointers will cause circular references and result in memory leaks. + /// \remarks + /// Only weak pointers provide thread-safe solution. The object is either atomically destroyed, + /// so that no other thread can obtain a reference to it through weak pointers. Or it is atomically + /// locked, so that strong reference is obtained. In this case no other thread can destroy the object, + /// because there is at least one strong reference now. Note however that removing the object from the + /// registry in the object's destructor may cause a deadlock at the point where Find() locks the weak pointer: + /// if other thread has started dtor, the object will be locked by Diligent::RefCountedObject::Release(). + /// If after that this thread locks the registry first, it will be waiting for the object to unlock in + /// Diligent::RefCntWeakPtr::Lock(), while the dtor thread will be waiting for the registry to unlock. + template<typename ResourceDescType> + class StateObjectsRegistry + { + public: + /// Number of outstanding deleted objects to purge the registry. + static const int DeletedObjectsToPurge = 32; + + StateObjectsRegistry(const Char* RegistryName) : + m_RegistryName( RegistryName ) + {} + + ~StateObjectsRegistry() + { + // Object registry is part of the device, and every device + // object holds a strong reference to the device. So device + // is destroyed after all device objects are destroyed, and there + // may only be expired references in the registry. After we + // purge it, the registry must be empty. + Purge(); + VERIFY( m_DescToObjHashMap.empty(), "DescToObjHashMap is not empty" ); + } + + /// Adds a new object to the registry + + /// \param [in] ObjectDesc - object description. + /// \param [in] pObject - pointer to the object. + /// + /// Besides adding a new object, the function also checks the number of + /// outstanding deleted objects and calls Purge() if the number has reached + /// the threshold value DeletedObjectsToPurge. Creating a state object is + /// assumed to be an expensive operation and should be performed during + /// the initialization. Occasional purge operations should not add significant + /// cost to it. + void Add( const ResourceDescType& ObjectDesc, IDeviceObject *pObject ) + { + ThreadingTools::LockHelper Lock( m_LockFlag ); + + // If the number of outstanding deleted objects reached the threshold value, + // purge the registry. Since we have exclusive access now, it is safe + // to do. + if( m_NumDeletedObjects >= DeletedObjectsToPurge ) + { + Purge(); + m_NumDeletedObjects = 0; + } + + // Try to construct the new element in place + auto Elems = m_DescToObjHashMap.emplace( std::make_pair( ObjectDesc, Diligent::RefCntWeakPtr<IDeviceObject>(pObject) ) ); + // It is theorertically possible that the same object can be found + // in the registry. This might happen if two threads try to create + // the same object at the same time. They both will not find the + // object and then will create and try to add it. + // + // If the object already exists, we replace the existing reference. + // This is safer as there might be scenarios where existing reference + // might be expired. For instance, two threads try to create the same + // object which is not in the registry. The first thread creates + // the object, adds it to the registry and then releases it. After that + // the second thread creates the same object and tries to add it to + // the registry. It will find an existing expired reference to the + // object. + if( !Elems.second ) + { + VERIFY( Elems.first->first == ObjectDesc, "Incorrect object description" ); + LOG_WARNING_MESSAGE( "Object named \"", Elems.first->first.Name, "\" with the same description already exists in the registry." + "Replacing with the new object named \"", ObjectDesc.Name ? ObjectDesc.Name : "", "\"."); + Elems.first->second = pObject; + } + } + + /// Finds the object in the registry + void Find( const ResourceDescType &Desc, IDeviceObject **ppObject ) + { + VERIFY( *ppObject == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + *ppObject = nullptr; + ThreadingTools::LockHelper Lock( m_LockFlag ); + + auto It = m_DescToObjHashMap.find( Desc ); + if( It != m_DescToObjHashMap.end() ) + { + // Try to obtain strong reference to the object. + // This is an atomic operation and we either get + // a new strong reference or object has been destroyed + // and we get null. + auto pObject = It->second.Lock(); + if( pObject ) + { + *ppObject = pObject.Detach(); + LOG_INFO_MESSAGE( "Equivalent of the requested state object named \"", Desc.Name ? Desc.Name : "", "\" found in the ", m_RegistryName, " registry. Reusing existing object."); + } + else + { + // Expired object found: remove it from the map + m_DescToObjHashMap.erase(It); + Atomics::AtomicDecrement(m_NumDeletedObjects); + } + } + } + + /// Purges outstanding deleted objects from the registry + void Purge() + { + Uint32 NumPurgedObjects = 0; + auto It = m_DescToObjHashMap.begin(); + while( It != m_DescToObjHashMap.end() ) + { + auto NextIt = It; + ++NextIt; + // Note that IsValid() is not a thread-safe function in the sense that it + // can give false positive results. The only thread-safe way to check if the + // object is alive is to lock the weak pointer, but that requires thread + // synchronization. We will immediately unlock the pointer anyway, so we + // want to detect 100% expired pointers. IsValid() does provide that information + // because once a weak pointer becomes invalid, it will be invalid + // until it is destroyed. It is not a problem if we miss an expired weak + // pointer as it will definitiely be removed next time. + if( !It->second.IsValid() ) + { + m_DescToObjHashMap.erase( It ); + ++NumPurgedObjects; + } + + It = NextIt; + } + LOG_INFO_MESSAGE( "Purged ", NumPurgedObjects, " deleted objects from the ", m_RegistryName, " registry" ); + } + + /// Increments the number of outstanding deleted objects. + /// When this number reaches DeletedObjectsToPurge, Purge() will + /// be called. + void ReportDeletedObject() + { + Atomics::AtomicIncrement(m_NumDeletedObjects); + } + + private: + /// Lock flag to protect the m_DescToObjHashMap + ThreadingTools::LockFlag m_LockFlag; + + /// Nmber of outstanding deleted objects that have not been purged + Atomics::AtomicLong m_NumDeletedObjects; + + /// Hash map that stores weak pointers to the referenced objects + std::unordered_map<ResourceDescType, Diligent::RefCntWeakPtr<IDeviceObject> > m_DescToObjHashMap; + + /// Registry name used for debug output + const String m_RegistryName; + }; +} diff --git a/Graphics/GraphicsEngine/include/SwapChainBase.h b/Graphics/GraphicsEngine/include/SwapChainBase.h new file mode 100644 index 00000000..c3400877 --- /dev/null +++ b/Graphics/GraphicsEngine/include/SwapChainBase.h @@ -0,0 +1,96 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::SwapChainBase template class + +#include "SwapChain.h" +#include "DeviceObjectBase.h" + +namespace Diligent +{ + +/// Base implementation of the swap chain. + +/// \remarks Swap chain holds the strong reference to the device and a weak reference to the +/// immediate context. +template<class BaseInterface = ISwapChain> +class SwapChainBase : public ObjectBase<BaseInterface> +{ +public: + typedef ObjectBase<BaseInterface> TObjectBase; + + SwapChainBase( IRenderDevice *pDevice, + IDeviceContext *pDeviceContext, + const SwapChainDesc& SCDesc ) : + m_pRenderDevice(pDevice), + m_wpDeviceContext(pDeviceContext), + m_SwapChainDesc(SCDesc) + { + } + + ~SwapChainBase() + { + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_SwapChain, TObjectBase ) + + virtual const SwapChainDesc& GetDesc()const + { + return m_SwapChainDesc; + } + +protected: + bool Resize( Uint32 NewWidth, Uint32 NewHeight, Int32 Dummy = 0/*To be different from virtual function*/ ) + { + if( NewWidth != 0 && NewHeight != 0 && + (m_SwapChainDesc.Width != NewWidth || m_SwapChainDesc.Height != NewHeight) ) + { + m_SwapChainDesc.Width = NewWidth; + m_SwapChainDesc.Height = NewHeight; + return true; + } + + return false; + } + + /// Strong reference to the render device + Diligent::RefCntAutoPtr<IRenderDevice> m_pRenderDevice; + + /// Weak references to the immediate device context. The context holds + /// the strong reference to the swap chain. + Diligent::RefCntWeakPtr<IDeviceContext> m_wpDeviceContext; + + /// Swap chain description + SwapChainDesc m_SwapChainDesc; + +private: + SwapChainBase( const SwapChainBase& ); + SwapChainBase( SwapChainBase&& ); + const SwapChainBase& operator = ( const SwapChainBase& ); + const SwapChainBase& operator = ( SwapChainBase&& ); +}; + +} diff --git a/Graphics/GraphicsEngine/include/TextureBase.h b/Graphics/GraphicsEngine/include/TextureBase.h new file mode 100644 index 00000000..094de62d --- /dev/null +++ b/Graphics/GraphicsEngine/include/TextureBase.h @@ -0,0 +1,394 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::TextureBase template class + +#include "Texture.h" +#include "DeviceObjectBase.h" +#include "GraphicsUtilities.h" +#include <memory> + +namespace Diligent +{ + +void ValidateTextureDesc(const TextureDesc& TexDesc); +void ValidateUpdateDataParams( const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); +void VliadateCopyTextureDataParams( const TextureDesc &SrcTexDesc, Uint32 SrcMipLevel, Uint32 SrcSlice, const Box *pSrcBox, + const TextureDesc &DstTexDesc, Uint32 DstMipLevel, Uint32 DstSlice, + Uint32 DstX, Uint32 DstY, Uint32 DstZ ); + +/// Base implementation of the ITexture interface + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::ITextureD3D11 or Diligent::ITextureGL). +/// \tparam TTextureViewImpl - type of the texture view implementation +/// (Diligent::TextureViewD3D11Impl or Diligent::TextureViewGLImpl). +template<class BaseInterface, class TTextureViewImpl> +class TextureBase : public DeviceObjectBase<BaseInterface, TextureDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, TextureDesc> TDeviceObjectBase; + + /// \param pDevice - pointer to the device + /// \param Desc - texture description + /// \param bIsDeviceInternal - flag indicating if the texture is an internal device object and + /// must not keep a strong reference to the device + TextureBase( IRenderDevice *pDevice, const TextureDesc& Desc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pDevice, Desc, nullptr, bIsDeviceInternal ) + { + if( this->m_Desc.MipLevels == 0 ) + { + // Compute the number of levels in the full mipmap chain based + // on the maximum texture dimension + Uint32 MaxDim = 0; + if( this->m_Desc.Type == TEXTURE_TYPE_1D || + this->m_Desc.Type == TEXTURE_TYPE_1D_ARRAY ) + { + MaxDim = this->m_Desc.Width; + } + else if( this->m_Desc.Type == TEXTURE_TYPE_2D || + this->m_Desc.Type == TEXTURE_TYPE_2D_ARRAY ) + { + MaxDim = std::max( this->m_Desc.Width, this->m_Desc.Height ); + } + else if( this->m_Desc.Type == TEXTURE_TYPE_3D ) + { + MaxDim = std::max( this->m_Desc.Width, this->m_Desc.Height ); + MaxDim = std::max( MaxDim, this->m_Desc.Depth ); + } + else + { + UNEXPECTED( "Unkwnown texture type" ); + } + while( (MaxDim >> this->m_Desc.MipLevels) > 0 ) + ++this->m_Desc.MipLevels; + VERIFY( MaxDim >= (1U << (this->m_Desc.MipLevels-1)) && MaxDim < (1U << this->m_Desc.MipLevels), "Incorrect number of Mip levels" ) + } + + // Validate correctness of texture description + ValidateTextureDesc( this->m_Desc ); + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_Texture, TDeviceObjectBase ) + + virtual void CreateView( const struct TextureViewDesc &ViewDesc, ITextureView **ppView )override + { + CreateViewInternal( ViewDesc, ppView, false ); + } + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) = 0; + + + virtual void CopyData( IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ ) = 0; + + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) = 0; + + virtual void Unmap( IDeviceContext *pContext ) = 0; + + void CreateDefaultViews(); + +protected: + + virtual void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView ) = 0; + + // WARNING! We cannot use ITextureView here, because ITextureView has no virtual dtor! + std::unique_ptr<TTextureViewImpl> m_pDefaultSRV; + std::unique_ptr<TTextureViewImpl> m_pDefaultRTV; + std::unique_ptr<TTextureViewImpl> m_pDefaultDSV; + std::unique_ptr<TTextureViewImpl> m_pDefaultUAV; + + ITextureView* GetDefaultView( TEXTURE_VIEW_TYPE ViewType )override + { + switch( ViewType ) + { + case TEXTURE_VIEW_SHADER_RESOURCE: return m_pDefaultSRV.get(); + case TEXTURE_VIEW_RENDER_TARGET: return m_pDefaultRTV.get(); + case TEXTURE_VIEW_DEPTH_STENCIL: return m_pDefaultDSV.get(); + case TEXTURE_VIEW_UNORDERED_ACCESS: return m_pDefaultUAV.get(); + default: UNEXPECTED( "Unknown view type" ); return nullptr; + } + } + + void CorrectTextureViewDesc( struct TextureViewDesc &ViewDesc ); + + // Corrects texture view format. For instance, if texture format is R32_TYPELESS, + // then for a depth-stencil view, the function will return D32_FLOAT, but for a shader resource + // view, it will return R32_FLOAT. + TEXTURE_FORMAT CorrectTextureViewFormat( TEXTURE_FORMAT Fmt, TEXTURE_VIEW_TYPE TexViewType ); +}; + + +template<class BaseInterface, class TTextureViewImpl> +TEXTURE_FORMAT TextureBase<BaseInterface, TTextureViewImpl> :: CorrectTextureViewFormat( TEXTURE_FORMAT Fmt, TEXTURE_VIEW_TYPE TexViewType ) +{ + // Correct texture view format for depth stencil view + if( TexViewType == TEXTURE_VIEW_DEPTH_STENCIL ) + { + if( Fmt == TEX_FORMAT_R32_FLOAT || Fmt == TEX_FORMAT_R32_TYPELESS ) + { + Fmt = TEX_FORMAT_D32_FLOAT; + } + else if( Fmt == TEX_FORMAT_R16_UNORM || Fmt == TEX_FORMAT_R16_TYPELESS ) + { + Fmt = TEX_FORMAT_D16_UNORM; + } + else if( Fmt == TEX_FORMAT_R24G8_TYPELESS || + Fmt == TEX_FORMAT_R24_UNORM_X8_TYPELESS || + Fmt == TEX_FORMAT_X24_TYPELESS_G8_UINT ) + { + Fmt = TEX_FORMAT_D24_UNORM_S8_UINT; + } + else if( Fmt == TEX_FORMAT_R32G8X24_TYPELESS || + Fmt == TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS || + Fmt == TEX_FORMAT_X32_TYPELESS_G8X24_UINT ) + { + Fmt = TEX_FORMAT_D32_FLOAT_S8X24_UINT; + } + } + else + { + // Correct texture view format for SR, RT or UA views + if( Fmt == TEX_FORMAT_D32_FLOAT || Fmt == TEX_FORMAT_R32_TYPELESS ) + { + Fmt = TEX_FORMAT_R32_FLOAT; + } + else if( Fmt == TEX_FORMAT_D16_UNORM || Fmt == TEX_FORMAT_R16_TYPELESS ) + { + Fmt = TEX_FORMAT_R16_UNORM; + } + else if( Fmt == TEX_FORMAT_D24_UNORM_S8_UINT || + Fmt == TEX_FORMAT_R24G8_TYPELESS ) + { + Fmt = TEX_FORMAT_R24_UNORM_X8_TYPELESS; + } + else if( Fmt == TEX_FORMAT_D32_FLOAT_S8X24_UINT || + Fmt == TEX_FORMAT_R32G8X24_TYPELESS ) + { + Fmt = TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS; + } + } + + return Fmt; +} + +template<class BaseInterface, class TTextureViewImpl> +void TextureBase<BaseInterface, TTextureViewImpl> :: CorrectTextureViewDesc(struct TextureViewDesc &ViewDesc) +{ +#define TEX_VIEW_VALIDATION_ERROR(...) LOG_ERROR_AND_THROW( "Texture view \"", ViewDesc.Name ? ViewDesc.Name : "", "\": ", ##__VA_ARGS__ ); + + if( !(ViewDesc.ViewType > TEXTURE_VIEW_UNDEFINED && ViewDesc.ViewType < TEXTURE_VIEW_NUM_VIEWS) ) + TEX_VIEW_VALIDATION_ERROR( "Texture view type is not specified" ); + + if( ViewDesc.MostDetailedMip + ViewDesc.NumMipLevels > this->m_Desc.MipLevels ) + TEX_VIEW_VALIDATION_ERROR( "Most detailed mip (", ViewDesc.MostDetailedMip, ") and number of mip levels in the view (", ViewDesc.NumMipLevels, ") specify more levels than target texture has (", this->m_Desc.MipLevels, ")" ); + + if( ViewDesc.Format == TEX_FORMAT_UNKNOWN ) + ViewDesc.Format = CorrectTextureViewFormat( this->m_Desc.Format, ViewDesc.ViewType ); + + if( ViewDesc.TextureType == TEXTURE_TYPE_UNDEFINED ) + ViewDesc.TextureType = this->m_Desc.Type; + + switch( this->m_Desc.Type ) + { + case TEXTURE_TYPE_1D: + if( ViewDesc.TextureType != TEXTURE_TYPE_1D ) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture 1D view: only Texture 1D is allowed" ); + } + break; + + case TEXTURE_TYPE_1D_ARRAY: + if( ViewDesc.TextureType != TEXTURE_TYPE_1D_ARRAY && + ViewDesc.TextureType != TEXTURE_TYPE_1D ) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect view type for Texture 1D Array: only Texture 1D or Texture 1D Array are allowed" ); + } + break; + + case TEXTURE_TYPE_2D: + if(ViewDesc.TextureType != TEXTURE_TYPE_2D ) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture 2D view: only Texture 2D is allowed" ); + } + break; + + case TEXTURE_TYPE_2D_ARRAY: + if( ViewDesc.TextureType != TEXTURE_TYPE_2D_ARRAY && + ViewDesc.TextureType != TEXTURE_TYPE_2D ) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture 2D Array view: only Texture 2D or Texture 2D Array are allowed" ); + } + break; + + case TEXTURE_TYPE_3D: + if( ViewDesc.TextureType != TEXTURE_TYPE_3D ) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture 3D view: only Texture 3D is allowed" ); + } + break; + + default: + UNEXPECTED( "Unexpected texture type" ); + break; + } + + if( ViewDesc.TextureType == TEXTURE_TYPE_1D_ARRAY || + ViewDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) + { + if( ViewDesc.FirstArraySlice + ViewDesc.NumArraySlices > this->m_Desc.ArraySize ) + TEX_VIEW_VALIDATION_ERROR( "First slice (", ViewDesc.FirstArraySlice, ") and number of slices in the view (", ViewDesc.NumArraySlices, ") specify more slices than target texture has (", this->m_Desc.ArraySize, ")" ); + } + else if( ViewDesc.TextureType == TEXTURE_TYPE_3D ) + { + auto MipDepth = this->m_Desc.Depth >> ViewDesc.MostDetailedMip; + if( ViewDesc.FirstDepthSlice + ViewDesc.NumDepthSlices > MipDepth ) + TEX_VIEW_VALIDATION_ERROR( "First slice (", ViewDesc.FirstDepthSlice, ") and number of slices in the view (", ViewDesc.NumDepthSlices, ") specify more slices than target 3D texture mip level has (", MipDepth, ")" ); + } +#undef TEX_VIEW_VALIDATION_ERROR + + if( ViewDesc.NumMipLevels == 0 ) + { + if( ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE ) + ViewDesc.NumMipLevels = this->m_Desc.MipLevels - ViewDesc.MostDetailedMip; + else + ViewDesc.NumMipLevels = 1; + } + + if( ViewDesc.NumArraySlices == 0 ) + { + if( ViewDesc.TextureType == TEXTURE_TYPE_1D_ARRAY || + ViewDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) + ViewDesc.NumArraySlices = this->m_Desc.ArraySize - ViewDesc.FirstArraySlice; + else if( ViewDesc.TextureType == TEXTURE_TYPE_3D ) + { + auto MipDepth = this->m_Desc.Depth >> ViewDesc.MostDetailedMip; + ViewDesc.NumDepthSlices = MipDepth - ViewDesc.FirstDepthSlice; + } + else + ViewDesc.NumArraySlices = 1; + } + + if( (ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET) && + ( ViewDesc.Format == TEX_FORMAT_R8_SNORM || ViewDesc.Format == TEX_FORMAT_RG8_SNORM || ViewDesc.Format == TEX_FORMAT_RGBA8_SNORM || + ViewDesc.Format == TEX_FORMAT_R16_SNORM || ViewDesc.Format == TEX_FORMAT_RG16_SNORM || ViewDesc.Format == TEX_FORMAT_RGBA16_SNORM ) ) + { + const auto *FmtName = GetTextureFormatAttribs( ViewDesc.Format ).Name; + LOG_WARNING_MESSAGE( FmtName, " render target view is created.\n" + "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero.\n" + "Use UNORM format instead." ); + } +} + +template<class BaseInterface, class TTextureViewImpl> +void TextureBase<BaseInterface, TTextureViewImpl> :: CreateDefaultViews() +{ + if(this->m_Desc.BindFlags & BIND_SHADER_RESOURCE ) + { + TextureViewDesc ViewDesc; + ViewDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE; + ITextureView *pSRV = nullptr; + CreateViewInternal( ViewDesc, &pSRV, true ); + m_pDefaultSRV.reset( static_cast<TTextureViewImpl*>(pSRV) ); + VERIFY( m_pDefaultSRV->GetDesc().ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Unexpected view type" ); + } + + if(this->m_Desc.BindFlags & BIND_RENDER_TARGET ) + { + TextureViewDesc ViewDesc; + ViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; + ITextureView *pRTV = nullptr; + CreateViewInternal( ViewDesc, &pRTV, true ); + m_pDefaultRTV.reset( static_cast<TTextureViewImpl*>(pRTV) ); + VERIFY( m_pDefaultRTV->GetDesc().ViewType == TEXTURE_VIEW_RENDER_TARGET, "Unexpected view type" ); + } + + if(this->m_Desc.BindFlags & BIND_DEPTH_STENCIL ) + { + TextureViewDesc ViewDesc; + ViewDesc.ViewType = TEXTURE_VIEW_DEPTH_STENCIL; + ITextureView *pDSV = nullptr; + CreateViewInternal( ViewDesc, &pDSV, true ); + m_pDefaultDSV.reset( static_cast<TTextureViewImpl*>(pDSV) ); + VERIFY( m_pDefaultDSV->GetDesc().ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Unexpected view type" ); + } + + if(this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS ) + { + TextureViewDesc ViewDesc; + ViewDesc.ViewType = TEXTURE_VIEW_UNORDERED_ACCESS; + ViewDesc.AccessFlags = UAV_ACCESS_FLAG_READ_WRITE; + ITextureView *pUAV = nullptr; + CreateViewInternal( ViewDesc, &pUAV, true ); + m_pDefaultUAV.reset( static_cast<TTextureViewImpl*>(pUAV) ); + VERIFY( m_pDefaultUAV->GetDesc().ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Unexpected view type" ); + } +} + + +template<class BaseInterface, class TTextureViewImpl> +void TextureBase<BaseInterface, TTextureViewImpl> :: UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + ValidateUpdateDataParams( this->m_Desc, MipLevel, Slice, DstBox, SubresData ); +} + +template<class BaseInterface, class TTextureViewImpl> +void TextureBase<BaseInterface, TTextureViewImpl> :: CopyData( IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ ) +{ + VERIFY( pContext, "pContext is null" ); + VERIFY( pSrcTexture, "pSrcTexture is null" ); + VliadateCopyTextureDataParams( pSrcTexture->GetDesc(), SrcMipLevel, SrcSlice, pSrcBox, + this->GetDesc(), DstMipLevel, DstSlice, DstX, DstY, DstZ ); +} + +template<class BaseInterface, class TTextureViewImpl> +void TextureBase<BaseInterface, TTextureViewImpl> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) +{ +} + +template<class BaseInterface, class TTextureViewImpl> +void TextureBase<BaseInterface, TTextureViewImpl> :: Unmap( IDeviceContext *pContext ) +{ +} + +} diff --git a/Graphics/GraphicsEngine/include/TextureViewBase.h b/Graphics/GraphicsEngine/include/TextureViewBase.h new file mode 100644 index 00000000..af2c93d8 --- /dev/null +++ b/Graphics/GraphicsEngine/include/TextureViewBase.h @@ -0,0 +1,90 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::TextureViewBase template class + +#include "TextureView.h" +#include "DeviceObjectBase.h" +#include "RefCntAutoPtr.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a texture view interface + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::ITextureViewD3D11 or Diligent::ITextureViewGL). +template<class BaseInterface = ITextureView> +class TextureViewBase : public DeviceObjectBase<BaseInterface, TextureViewDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, TextureViewDesc> TDeviceObjectBase; + + TextureViewBase( IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + class ITexture *pTexture, + bool bIsDefaultView ) : + // Default views are created as part of the texture, so we cannot not keep strong + // reference to the texture to avoid cyclic links. Instead, we will attach to the + // reference counters of the texture. + TDeviceObjectBase( pDevice, ViewDesc, bIsDefaultView ? pTexture : nullptr ), + m_pTexture( pTexture ), + // For non-default view, we will keep strong reference to texture + m_spTexture(bIsDefaultView ? nullptr : pTexture) + {} + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_TextureView, TDeviceObjectBase ) + + virtual void SetSampler( class ISampler *pSampler ) + { + VERIFY( this->m_Desc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Texture view \"", this->m_Desc.Name, "\": A sampler can be attached to a shader resource view only. The view type is ", GetTexViewTypeLiteralName(this->m_Desc.ViewType) ); + m_pSampler = pSampler; + } + + virtual ISampler* GetSampler() + { + return m_pSampler; + } + + virtual ITexture* GetTexture() + { + return m_pTexture; + } + +protected: + /// Strong reference to the sampler + Diligent::RefCntAutoPtr<ISampler> m_pSampler; + + /// Raw pointer to the texture + ITexture *m_pTexture; + + /// Strong reference to the texture. Used for non-default views + /// to keep the texture alive + Diligent::RefCntAutoPtr<ITexture> m_spTexture; +}; + +} diff --git a/Graphics/GraphicsEngine/include/VertexDescriptionBase.h b/Graphics/GraphicsEngine/include/VertexDescriptionBase.h new file mode 100644 index 00000000..fdab3db6 --- /dev/null +++ b/Graphics/GraphicsEngine/include/VertexDescriptionBase.h @@ -0,0 +1,96 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::VertexDescriptionBase template class + +#include "VertexDescription.h" +#include "DeviceObjectBase.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a vertex description object + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IVertexDescriptionD3D11 or Diligent::IVertexDescriptionGL). +template<class BaseInterface = IVertexDescription> +class VertexDescriptionBase : public DeviceObjectBase<BaseInterface, LayoutDesc> +{ +public: + typedef DeviceObjectBase<BaseInterface, LayoutDesc> TDeviceObjectBase; + + /// \param pDevice - pointer to the device. + /// \param LayoutDesc - layout description. + /// \param bIsDeviceInternal - flag indicating if the vertex description is an internal device object and + /// must not keep a strong reference to the device. + VertexDescriptionBase( IRenderDevice *pDevice, const LayoutDesc &LayoutDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pDevice, LayoutDesc, nullptr, bIsDeviceInternal), + m_TightStrides( MaxBufferSlots ), // The size of this array must be equal to the + // maximum number of buffer slots, because a layout + // element can refer to any input slot + m_LayoutElements( LayoutDesc.NumElements ) + { + for( size_t Elem = 0; Elem < LayoutDesc.NumElements; ++Elem ) + m_LayoutElements[Elem] = LayoutDesc.LayoutElements[Elem]; + this->m_Desc.LayoutElements = m_LayoutElements.data(); + + // Correct description and compute offsets and tight strides + for( auto It = m_LayoutElements.begin(); It != m_LayoutElements.end(); ++It ) + { + if( It->ValueType == VT_FLOAT32 || It->ValueType == VT_FLOAT16 ) + It->IsNormalized = false; // Floating point values cannot be normalized + + auto BuffSlot = It->BufferSlot; + if( BuffSlot >= m_TightStrides.size() ) + m_TightStrides.resize( BuffSlot + 1 ); + + auto &CurrStride = m_TightStrides[BuffSlot]; + if( It->RelativeOffset < CurrStride ) + { + if( It->RelativeOffset == 0 ) + It->RelativeOffset = CurrStride; + else + UNEXPECTED( "Overlapping layout elements" ); + } + + CurrStride += It->NumComponents * GetValueSize( It->ValueType ); + } + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_VertexDescription, TDeviceObjectBase ) + + virtual const Uint32* GetTightStrides() + { + return m_TightStrides.data(); + } + +protected: + std::vector<LayoutElement> m_LayoutElements; + std::vector<Uint32> m_TightStrides; +}; + +} diff --git a/Graphics/GraphicsEngine/include/pch.h b/Graphics/GraphicsEngine/include/pch.h new file mode 100644 index 00000000..c911c398 --- /dev/null +++ b/Graphics/GraphicsEngine/include/pch.h @@ -0,0 +1,41 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +/// \file +/// Precomputed header + +#pragma once + +#include <vector> +#include <list> +#include <set> +#include <map> +#include <unordered_map> +#include <memory> +#include <algorithm> +#include "GraphicsTypes.h" +#include "RefCntAutoPtr.h" +#include "Errors.h" +#include "DebugUtilities.h" +#include "RenderDeviceBase.h" +#include "DeviceContextBase.h"
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/interface/BlendState.h b/Graphics/GraphicsEngine/interface/BlendState.h new file mode 100644 index 00000000..3673bfae --- /dev/null +++ b/Graphics/GraphicsEngine/interface/BlendState.h @@ -0,0 +1,344 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBlendState interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +/// IBlendState interface unique identifier +// {81CFB7AC-6B9F-45FA-ACE2-CC6A9EDE4E75} +static const Diligent::INTERFACE_ID IID_BlendState = +{ 0x81cfb7ac, 0x6b9f, 0x45fa, { 0xac, 0xe2, 0xcc, 0x6a, 0x9e, 0xde, 0x4e, 0x75 } }; + + +/// Blend factors + +/// [D3D11_BLEND]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476086(v=vs.85).aspx +/// [glBlendFuncSeparate]: https://www.opengl.org/wiki/GLAPI/glBlendFuncSeparate +/// This enumeration defines blend factors for alpha-blending. +/// It generatlly mirrows [D3D11_BLEND][] enumeration and is used by RenderTargetBlendDesc structure +/// to define source and destination blend factors for color and alpha channels. +/// \sa [D3D11_BLEND on MSDN][D3D11_BLEND], [glBlendFuncSeparate on OpenGL.org][glBlendFuncSeparate] +enum BLEND_FACTOR : Int32 +{ + /// Undefined blend factor + BLEND_FACTOR_UNDEFINED = 0, + + /// The blend factor is zero.\n + /// D3D11 counterpart: D3D11_BLEND_ZERO. OpenGL counterpart: GL_ZERO. + BLEND_FACTOR_ZERO, + + /// The blend factor is one.\n + /// D3D11 counterpart: D3D11_BLEND_ONE. OpenGL counterpart: GL_ONE. + BLEND_FACTOR_ONE, + + /// The blend factor is RGB data from a pixel shader.\n + /// D3D11 counterpart: D3D11_BLEND_SRC_COLOR. OpenGL counterpart: GL_SRC_COLOR. + BLEND_FACTOR_SRC_COLOR, + + /// The blend factor is 1-RGB, where RGB is the data from a pixel shader.\n + /// D3D11 counterpart: D3D11_BLEND_INV_SRC_COLOR. OpenGL counterpart: GL_ONE_MINUS_SRC_COLOR. + BLEND_FACTOR_INV_SRC_COLOR, + + /// The blend factor is alpha (A) data from a pixel shader.\n + /// D3D11 counterpart: D3D11_BLEND_SRC_ALPHA. OpenGL counterpart: GL_SRC_ALPHA. + BLEND_FACTOR_SRC_ALPHA, + + /// The blend factor is 1-A, where A is alpha data from a pixel shader.\n + /// D3D11 counterpart: D3D11_BLEND_INV_SRC_ALPHA. OpenGL counterpart: GL_ONE_MINUS_SRC_ALPHA. + BLEND_FACTOR_INV_SRC_ALPHA, + + /// The blend factor is alpha (A) data from a render target.\n + /// D3D11 counterpart: D3D11_BLEND_DEST_ALPHA. OpenGL counterpart: GL_DST_ALPHA. + BLEND_FACTOR_DEST_ALPHA, + + /// The blend factor is 1-A, where A is alpha data from a render target.\n + /// D3D11 counterpart: D3D11_BLEND_INV_DEST_ALPHA. OpenGL counterpart: GL_ONE_MINUS_DST_ALPHA. + BLEND_FACTOR_INV_DEST_ALPHA, + + /// The blend factor is RGB data from a render target.\n + /// D3D11 counterpart: D3D11_BLEND_DEST_COLOR. OpenGL counterpart: GL_DST_COLOR. + BLEND_FACTOR_DEST_COLOR, + + /// The blend factor is 1-RGB, where RGB is the data from a render target.\n + /// D3D11 counterpart: D3D11_BLEND_INV_DEST_COLOR. OpenGL counterpart: GL_ONE_MINUS_DST_COLOR. + BLEND_FACTOR_INV_DEST_COLOR, + + /// The blend factor is (f,f,f,1), where f = min(As, 1-Ad), + /// As is alpha data from a pixel shader, and Ad is alpha data from a render target.\n + /// D3D11 counterpart: D3D11_BLEND_SRC_ALPHA_SAT. OpenGL counterpart: GL_SRC_ALPHA_SATURATE. + BLEND_FACTOR_SRC_ALPHA_SAT, + + /// The blend factor is the constant blend factor set with IDeviceContext::SetBlendState().\n + /// D3D11 counterpart: D3D11_BLEND_BLEND_FACTOR. OpenGL counterpart: GL_CONSTANT_COLOR. + BLEND_FACTOR_BLEND_FACTOR, + + /// The blend factor is one minus constant blend factor set with IDeviceContext::SetBlendState().\n + /// D3D11 counterpart: D3D11_BLEND_INV_BLEND_FACTOR. OpenGL counterpart: GL_ONE_MINUS_CONSTANT_COLOR. + BLEND_FACTOR_INV_BLEND_FACTOR, + + /// The blend factor is the second RGB data output from a pixel shader.\n + /// D3D11 counterpart: D3D11_BLEND_SRC1_COLOR. OpenGL counterpart: GL_SRC1_COLOR. + BLEND_FACTOR_SRC1_COLOR, + + /// The blend factor is 1-RGB, where RGB is the second RGB data output from a pixel shader.\n + /// D3D11 counterpart: D3D11_BLEND_INV_SRC1_COLOR. OpenGL counterpart: GL_ONE_MINUS_SRC1_COLOR. + BLEND_FACTOR_INV_SRC1_COLOR, + + /// The blend factor is the second alpha (A) data output from a pixel shader.\n + /// D3D11 counterpart: D3D11_BLEND_SRC1_ALPHA. OpenGL counterpart: GL_SRC1_ALPHA. + BLEND_FACTOR_SRC1_ALPHA, + + /// The blend factor is 1-A, where A is the second alpha data output from a pixel shader.\n + /// D3D11 counterpart: D3D11_BLEND_INV_SRC1_ALPHA. OpenGL counterpart: GL_ONE_MINUS_SRC1_ALPHA. + BLEND_FACTOR_INV_SRC1_ALPHA, + + /// Helper value that stores the total number of blend factors in the enumeration. + BLEND_FACTOR_NUM_FACTORS +}; + +/// Blending operation + +/// [D3D11_BLEND_OP]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476088(v=vs.85).aspx +/// [glBlendEquationSeparate]: https://www.opengl.org/wiki/GLAPI/glBlendEquationSeparate +/// This enumeration describes blending operation for RGB or Alpha channels and generally mirrows +/// [D3D11_BLEND_OP][] enum. It is used by RenderTargetBlendDesc structure to define RGB and Alpha +/// blending operations +/// \sa [D3D11_BLEND_OP on MSDN][D3D11_BLEND_OP], [glBlendEquationSeparate on OpenGL.org][glBlendEquationSeparate] +enum BLEND_OPERATION : Int32 +{ + /// Undefined blend operation + BLEND_OPERATION_UNDEFINED = 0, + + /// Add source and destination color components.\n + /// D3D11 counterpart: D3D11_BLEND_OP_ADD. OpenGL counterpart: GL_FUNC_ADD. + BLEND_OPERATION_ADD, + + /// Subtract destination color components from source color components.\n + /// D3D11 counterpart: D3D11_BLEND_OP_SUBTRACT. OpenGL counterpart: GL_FUNC_SUBTRACT. + BLEND_OPERATION_SUBTRACT, + + /// Subtract source color components from destination color components.\n + /// D3D11 counterpart: D3D11_BLEND_OP_REV_SUBTRACT. OpenGL counterpart: GL_FUNC_REVERSE_SUBTRACT. + BLEND_OPERATION_REV_SUBTRACT, + + /// Compute the minimum of source and destination color components.\n + /// D3D11 counterpart: D3D11_BLEND_OP_MIN. OpenGL counterpart: GL_MIN. + BLEND_OPERATION_MIN, + + /// Compute the maximum of source and destination color components.\n + /// D3D11 counterpart: D3D11_BLEND_OP_MAX. OpenGL counterpart: GL_MAX. + BLEND_OPERATION_MAX, + + /// Helper value that stores the total number of blend operations in the enumeration. + BLEND_OPERATION_NUM_OPERATIONS +}; + +/// Color component write flags + +/// These flags are used by RenderTargetBlendDesc structure to define +/// writable components of the render target +enum COLOR_MASK : Int32 +{ + /// Allow data to be stored in the red component. + COLOR_MASK_RED = 1, + + /// Allow data to be stored in the green component. + COLOR_MASK_GREEN = 2, + + /// Allow data to be stored in the blue component. + COLOR_MASK_BLUE = 4, + + /// Allow data to be stored in the alpha component. + COLOR_MASK_ALPHA = 8, + + /// Allow data to be stored in all components. + COLOR_MASK_ALL = ( ( ( COLOR_MASK_RED | COLOR_MASK_GREEN ) | COLOR_MASK_BLUE ) | COLOR_MASK_ALPHA ) +}; + +/// Describes a blend state for a single render target + +/// This structure is used by BlendStateDesc to describe +/// blend states for render targets +struct RenderTargetBlendDesc +{ + /// Enable or disable blending for this render target. + Bool BlendEnable; + + /// Specifies the blend factor to apply to the RGB value output from the pixel shader + BLEND_FACTOR SrcBlend; + + /// Specifies the blend factor to apply to the RGB value in the render target + BLEND_FACTOR DestBlend; + + /// Defines how to combine the source and destination RGB values + /// after applying the SrcBlend and DestBlend factors. + BLEND_OPERATION BlendOp; + + /// Specifies the blend factor to apply to the alpha value output from the pixel shader. + /// Blend factors that end in _COLOR are not allowed. + BLEND_FACTOR SrcBlendAlpha; + + /// Specifies the blend factor to apply to the alpha value in the render target. + /// Blend factors that end in _COLOR are not allowed. + BLEND_FACTOR DestBlendAlpha; + + /// Defines how to combine the source and destination alpha values + /// after applying the SrcBlendAlpha and DestBlendAlpha factors. + BLEND_OPERATION BlendOpAlpha; + + /// Render target write mask + Uint32 RenderTargetWriteMask; + + /// Constructor initializes structure members with default values + + /// Member | Default value + /// ----------------------|-------------- + /// BlendEnable | False + /// SrcBlend | BLEND_FACTOR_ONE + /// DestBlend | BLEND_FACTOR_ZERO + /// BlendOp | BLEND_OPERATION_ADD + /// SrcBlendAlpha | BLEND_FACTOR_ONE + /// DestBlendAlpha | BLEND_FACTOR_ZERO + /// BlendOpAlpha | BLEND_OPERATION_ADD + /// RenderTargetWriteMask | COLOR_MASK_ALL + RenderTargetBlendDesc() : + BlendEnable ( False ), + SrcBlend ( BLEND_FACTOR_ONE ), + DestBlend ( BLEND_FACTOR_ZERO ), + BlendOp ( BLEND_OPERATION_ADD ), + SrcBlendAlpha ( BLEND_FACTOR_ONE ), + DestBlendAlpha ( BLEND_FACTOR_ZERO ), + BlendOpAlpha ( BLEND_OPERATION_ADD ), + RenderTargetWriteMask( COLOR_MASK_ALL ) + {} + + + /// Comparison operator tests if two structures are equivalent + + /// \param [in] rhs - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise + bool operator == (const RenderTargetBlendDesc& rhs)const + { + return BlendEnable == rhs.BlendEnable && + SrcBlend == rhs.SrcBlend && + DestBlend == rhs.DestBlend && + BlendOp == rhs.BlendOp && + SrcBlendAlpha == rhs.SrcBlendAlpha && + DestBlendAlpha == rhs.DestBlendAlpha && + BlendOpAlpha == rhs.BlendOpAlpha && + RenderTargetWriteMask == rhs.RenderTargetWriteMask; + } +}; + +/// Blend state description + +/// This structure describes the blend state which is used in a call to +/// IRenderDevice::CreateBlendState() to create a blend state object +struct BlendStateDesc : DeviceObjectAttribs +{ + /// Specifies whether to use alpha-to-coverage as a multisampling technique + /// when setting a pixel to a render target. Default value: False. + Bool AlphaToCoverageEnable; + + /// Specifies whether to enable independent blending in simultaneous render targets. + /// If set to False, only RenderTargets[0] is used. Default value: False. + Bool IndependentBlendEnable; + + /// Constant member defining the maximum number of render targets + static const int MaxRenderTargets = 8; + + /// An array of RenderTargetBlendDesc structures that describe the blend + /// states for render targets + RenderTargetBlendDesc RenderTargets[MaxRenderTargets]; + + /// Constructor initializes structure members with default values + + /// Member | Default value + /// ----------------------|-------------- + /// AlphaToCoverageEnable | False + /// IndependentBlendEnable| False + /// + /// Members of RenderTargets[] are initialized with default values by + /// RenderTargetBlendDesc::RenderTargetBlendDesc() + BlendStateDesc() : + AlphaToCoverageEnable(False), + IndependentBlendEnable(False) + { + } + + /// Comparison operator tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members are of the two structures equal. + /// \note The operator performs *bitwise comparison* of the two structures. + /// That is if for instance both structures have IndependentBlendEnable set to False, + /// but differ in render target other than 0, the operator will return False + /// even though the two blend states created from these structures will be identical. + /// - False otherwise + /// \remarks + /// The operator ignores DeviceObjectAttribs::Name field as it does not affect the blend state. + bool operator == (const BlendStateDesc& RHS)const + { + bool bRTsEqual = true; + for( int i = 0; i < MaxRenderTargets; ++i ) + if( !(RenderTargets[i] == RHS.RenderTargets[i]) ) + { + bRTsEqual = false; + break; + } + + return bRTsEqual && + // Name is primarily used for debug purposes and does not affect the state. + // It is ignored in comparison operation. + // strcmp(Name, RHS.Name) == 0 && + AlphaToCoverageEnable == RHS.AlphaToCoverageEnable && + IndependentBlendEnable== RHS.IndependentBlendEnable; + } +}; + +/// Blend state interface + +/// The interface holds the blending state that can be bound to the pipeline by a call +/// to IDeviceContext::SetBlendState(). To create a blend state, call +/// IRenderDevice::CreateBlendState(). +class IBlendState : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details. + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the blend state description used to create the object + virtual const BlendStateDesc& GetDesc()const = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/Buffer.h b/Graphics/GraphicsEngine/interface/Buffer.h new file mode 100644 index 00000000..45dc21bc --- /dev/null +++ b/Graphics/GraphicsEngine/interface/Buffer.h @@ -0,0 +1,234 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Defines Diligent::IBuffer interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +// {EC47EAD3-A2C4-44F2-81C5-5248D14F10E4} +static const Diligent::INTERFACE_ID IID_Buffer = +{ 0xec47ead3, 0xa2c4, 0x44f2, { 0x81, 0xc5, 0x52, 0x48, 0xd1, 0x4f, 0x10, 0xe4 } }; + +/// Describes the buffer access mode. + +/// This enumeration is used by BufferDesc structure. +enum BUFFER_MODE : Int32 +{ + /// Undefined mode. + BUFFER_MODE_UNDEFINED = 0, + + /// Formated buffer. + BUFFER_MODE_FORMATED, + + /// Structured buffer. + BUFFER_MODE_STRUCTURED, + + /// Helper value storing the total number of modes in the enumeration. + BUFFER_MODE_NUM_MODES +}; + +/// Buffer description +struct BufferDesc : DeviceObjectAttribs +{ + /// Size of the buffer, in bytes. For a uniform buffer, this must be multiple of 16. + Uint32 uiSizeInBytes; + + /// Buffer bind flags, see Diligent::BIND_FLAGS for details + + /// The following bind flags are allowed: + /// Diligent::BIND_VERTEX_BUFFER, Diligent::BIND_INDEX_BUFFER, Diligent::BIND_UNIFORM_BUFFER, + /// Diligent::BIND_SHADER_RESOURCE, Diligent::BIND_STREAM_OUTPUT, Diligent::BIND_UNORDERED_ACCESS, + /// Diligent::BIND_INDIRECT_DRAW_ARGS + Uint32 BindFlags; + + /// Buffer usage, see Diligent::USAGE for details + USAGE Usage; + + /// CPU access flags or 0 if no CPU access is allowed, + /// see Diligent::CPU_ACCESS_FLAG for details. + Uint32 CPUAccessFlags; + + /// Buffer mode + BUFFER_MODE Mode; + + /// Buffer format description + struct BufferFormat + { + /// Type of components. For a formatted buffer, this value cannot be VT_UNDEFINED + VALUE_TYPE ValueType; + + /// Number of components. Allowed values: 1, 2, 3, 4. + /// For a formatted buffer, this value cannot be 0 + Uint32 NumComponents; + + /// For signed and unsigned integer value types + /// (VT_INT8, VT_INT16, VT_INT32, VT_UINT8, VT_UINT16, VT_UINT32) + /// indicates if the value should be normalized to [-1,+1] or + /// [0, 1] range respectively. For floating point types + /// (VT_FLOAT16 and VT_FLOAT32), this member is ignored. + Bool IsNormalized; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// --------------------|-------------- + /// ValueType | VT_UNDEFINED + /// NumComponents | 0 + /// IsNormalized | True + BufferFormat() : + ValueType( VT_UNDEFINED ), + NumComponents( 0 ), + IsNormalized(True) + {} + }; + + /// Buffer format + + /// For a formatted buffer (BufferDesc::Mode equals Diligent::BUFFER_MODE_FORMATED), this member describes the + /// buffer format, see BufferFormat. Ignored otherwise. + BufferFormat Format; + + /// Buffer element stride, in bytes. For a structured buffer (BufferDesc::Mode + /// equals Diligent::BUFFER_MODE_STRUCTURED), this member cannot be zero. For a formatted buffer + /// (BufferDesc::Mode equals Diligent::BUFFER_MODE_FORMATED), this member can either specify the stride, or + /// be 0. In the latter case, the stride is computed automatically based + /// on the format size and assuming that elements are densely packed. + Uint32 ElementByteStride; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// --------------------|-------------- + /// uiSizeInBytes | 0 + /// BindFlags | 0 + /// Usage | USAGE_DEFAULT + /// CPUAccessFlags | 0 + /// Mode | BUFFER_MODE_UNDEFINED + /// ElementByteStride | 0 + /// Members of BufferDesc::Format are initialized with default values by BufferFormat::BufferFormat() + BufferDesc() : + uiSizeInBytes(0), + BindFlags(0), + Usage(USAGE_DEFAULT), + CPUAccessFlags(0), + Mode( BUFFER_MODE_UNDEFINED ), + ElementByteStride(0) + {} +}; + +/// Describes the buffer initial data +struct BufferData +{ + /// Pointer to the data + PVoid pData; + + /// Data size, in bytes + Uint32 DataSize; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// --------------------|-------------- + /// pData | nullptr + /// DataSize | 0 + BufferData() : + pData(nullptr), + DataSize(0) + {} +}; + +/// Buffer interface + +/// Defines the methods to manipulate a buffer object +class IBuffer : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the buffer description used to create the object + virtual const BufferDesc& GetDesc()const = 0; + + /// Updates the data in the buffer + + /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation. + /// \param [in] Offset - Offset in bytes from the beginning of the buffer to the update region. + /// \param [in] Size - Size in bytes of the data region to update. + /// \param [in] pData - Pointer to the data to store in the buffer. + virtual void UpdateData( class IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData) = 0; + + /// Copies the data from other buffer + + /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation. + /// \param [in] pSrcBuffer - Source buffer to copy data from. + /// \param [in] SrcOffset - Offset in bytes from the beginning of the source buffer to the beginning of data to copy. + /// \param [in] DstOffset - Offset in bytes from the beginning of the destination buffer to the beginning + /// of the destination region. + /// \param [in] Size - Size in bytes of data to copy. + virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size ) = 0; + + /// Maps the buffer + + /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation. + /// \param [in] MapType - Type of the map operation. See Diligent::MAP_TYPE. + /// \param [in] MapFlags - Special map flags. See Diligent::MAP_FLAGS. + /// \param [out] pMappedData - Reference to the void pointer to store the address of the mapped region. + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) = 0; + + /// Unmaps the previously mapped buffer + /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation. + virtual void Unmap( IDeviceContext *pContext ) = 0; + + /// Creates a new buffer view + + /// \param [in] ViewDesc - View description. See Diligent::BufferViewDesc for details. + /// \param [out] ppView - Address of the memory location where the pointer to the view interface will be written to. + /// + /// \remarks To create a view addressing the entire buffer, set only BufferViewDesc::ViewType member + /// of the ViewDesc structure and leave all other members in their default values.\n + /// Buffer view will contain strong reference to the buffer, so the buffer will not be destroyed + /// until all views are released.\n + /// The function calls AddRef() for the created interface, so it must be released by + /// a call to Release() when it is no longer needed. + virtual void CreateView( const struct BufferViewDesc &ViewDesc, class IBufferView **ppView ) = 0; + + /// Returns the pointer to the default view. + + /// \param [in] ViewType - Type of the requested view. See Diligent::BUFFER_VIEW_TYPE. + /// \return Pointer to the interface + /// + /// \note The function does not increase the reference counter for the returned interface, so + /// Release() must *NOT* be called. + virtual IBufferView* GetDefaultView( BUFFER_VIEW_TYPE ViewType ) = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/BufferView.h b/Graphics/GraphicsEngine/interface/BufferView.h new file mode 100644 index 00000000..93d52887 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/BufferView.h @@ -0,0 +1,107 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBufferView interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +// {E2E83490-E9D2-495B-9A83-ABB413A38B07} +static const Diligent::INTERFACE_ID IID_BufferView = +{ 0xe2e83490, 0xe9d2, 0x495b, { 0x9a, 0x83, 0xab, 0xb4, 0x13, 0xa3, 0x8b, 0x7 } }; + +/// Buffer view description +struct BufferViewDesc : DeviceObjectAttribs +{ + /// View type. See Diligent::BUFFER_VIEW_TYPE for details. + BUFFER_VIEW_TYPE ViewType; + + /// Offset in bytes from the beginnig of the buffer to the start of the + /// buffer region referenced by the view + Uint32 ByteOffset; + + /// Size in bytes of the referenced buffer region + Uint32 ByteWidth; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// --------------------|-------------- + /// ViewType | BUFFER_VIEW_UNDEFINED + /// ByteOffset | 0 + /// ByteWidth | 0 + BufferViewDesc() : + ViewType( BUFFER_VIEW_UNDEFINED ), + ByteOffset(0), + ByteWidth(0) + { + } + + /// Comparison operator tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise + /// \remarks + /// The operator ignores DeviceObjectAttribs::Name field. + bool operator == (const BufferViewDesc& RHS)const + { + // Name is primarily used for debug purposes and does not affect the view. + // It is ignored in comparison operation. + return //strcmp(Name, RHS.Name) == 0 && + ViewType == RHS.ViewType && + ByteOffset== RHS.ByteOffset && + ByteWidth == RHS.ByteWidth; + } +}; + +/// Buffer view interface + +/// To create a buffer view, call IBuffer::CreateView(). +/// \remarks +/// Buffer view holds strong references to the buffer. The buffer +/// will not be destroyed until all views are released. +class IBufferView : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the buffer view description used to create the object + virtual const BufferViewDesc& GetDesc()const = 0; + + /// Returns pointer to the referenced buffer object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual IBuffer* GetBuffer() = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/Constants.h b/Graphics/GraphicsEngine/interface/Constants.h new file mode 100644 index 00000000..50d9d427 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/Constants.h @@ -0,0 +1,36 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the engine constants + +namespace Diligent +{ + /// Maximum number of input buffer slots. + static const Uint32 MaxBufferSlots = 32; + + /// Maximum number of simultaneous render targets. + static const Uint32 MaxRenderTargets = 8; +} diff --git a/Graphics/GraphicsEngine/interface/DepthStencilState.h b/Graphics/GraphicsEngine/interface/DepthStencilState.h new file mode 100644 index 00000000..75347935 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/DepthStencilState.h @@ -0,0 +1,238 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IDepthStencilState interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +// {51C3A67F-FADD-411A-BA36-BDE9EE29722B} +static const Diligent::INTERFACE_ID IID_DepthStencilState = +{ 0x51c3a67f, 0xfadd, 0x411a, { 0xba, 0x36, 0xbd, 0xe9, 0xee, 0x29, 0x72, 0x2b } }; + +/// Stencil operation + +/// [D3D11_STENCIL_OP]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476219(v=vs.85).aspx +/// This enumeration describes the stencil operation and generally mirrows +/// [D3D11_STENCIL_OP][] enumeration. +/// It is used by Diligent::StencilOpDesc structure to describe the stencil fail, depth fail +/// and stencil pass operations +enum STENCIL_OP : Int32 +{ + /// Undefined operation. + STENCIL_OP_UNDEFINED = 0, + + /// Keep the existing stencil data.\n + /// D3D11 Counterpart: D3D11_STENCIL_OP_KEEP. OpenGL counterpart: GL_KEEP. + STENCIL_OP_KEEP = 1, + + /// Set the stencil data to 0.\n + /// D3D11 Counterpart: D3D11_STENCIL_OP_ZERO. OpenGL counterpart: GL_ZERO. + STENCIL_OP_ZERO = 2, + + /// Set the stencil data to the reference value set by calling IDeviceContext::SetDepthStencilState().\n + /// D3D11 Counterpart: D3D11_STENCIL_OP_REPLACE. OpenGL counterpart: GL_REPLACE. + STENCIL_OP_REPLACE = 3, + + /// Increment the current stencil value, and clamp to the maximum representable unsigned value.\n + /// D3D11 Counterpart: D3D11_STENCIL_OP_INCR_SAT. OpenGL counterpart: GL_INCR. + STENCIL_OP_INCR_SAT = 4, + + /// Decrement the current stencil value, and clamp to 0.\n + /// D3D11 Counterpart: D3D11_STENCIL_OP_DECR_SAT. OpenGL counterpart: GL_DECR. + STENCIL_OP_DECR_SAT = 5, + + /// Bitwise invert the current stencil buffer value.\n + /// D3D11 Counterpart: D3D11_STENCIL_OP_INVERT. OpenGL counterpart: GL_INVERT. + STENCIL_OP_INVERT = 6, + + /// Increment the current stencil value, and wrap the value to zero when incrementing + /// the maximum representable unsigned value. \n + /// D3D11 Counterpart: D3D11_STENCIL_OP_INCR. OpenGL counterpart: GL_INCR_WRAP. + STENCIL_OP_INCR_WRAP = 7, + + /// Decrement the current stencil value, and wrap the value to the maximum representable + /// unsigned value when decrementing a value of zero.\n + /// D3D11 Counterpart: D3D11_STENCIL_OP_DECR. OpenGL counterpart: GL_DECR_WRAP. + STENCIL_OP_DECR_WRAP = 8, + + /// Helper value that stores the total number of stencil operations in the enumeration. + STENCIL_OP_NUM_OPS +}; + +/// Describes stencil operations that are performed based on the results of depth test. + +/// [D3D11_DEPTH_STENCILOP_DESC]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476109(v=vs.85).aspx +/// The structure generally mirrows [D3D11_DEPTH_STENCILOP_DESC][] structure. +/// It is used by Diligent::DepthStencilStateDesc structure to describe the stencil +/// operations for the front and back facing polygons. +struct StencilOpDesc +{ + /// The stencil operation to perform when stencil testing fails. + STENCIL_OP StencilFailOp; + + /// The stencil operation to perform when stencil testing passes and depth testing fails. + STENCIL_OP StencilDepthFailOp; + + /// The stencil operation to perform when stencil testing and depth testing both pass. + STENCIL_OP StencilPassOp; + + /// A function that compares stencil data against existing stencil data. See + /// Diligent::COMPARISON_FUNCTION. + COMPARISON_FUNCTION StencilFunc; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// --------------------|-------------- + /// StencilFailOp | STENCIL_OP_KEEP + /// StencilDepthFailOp | STENCIL_OP_KEEP + /// StencilPassOp | STENCIL_OP_KEEP + /// StencilFunc | COMPARISON_FUNC_ALWAYS + StencilOpDesc() : + StencilFailOp ( STENCIL_OP_KEEP ), + StencilDepthFailOp( STENCIL_OP_KEEP ), + StencilPassOp ( STENCIL_OP_KEEP ), + StencilFunc ( COMPARISON_FUNC_ALWAYS ) + {} + + /// Tests if two structures are equivalent + + /// \param [in] rhs - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise + bool operator == (const StencilOpDesc& rhs)const + { + return StencilFailOp == rhs.StencilFailOp && + StencilDepthFailOp == rhs.StencilDepthFailOp && + StencilPassOp == rhs.StencilPassOp && + StencilFunc == rhs.StencilFunc; + } +}; + +/// Depth stencil state description + +/// [D3D11_DEPTH_STENCIL_DESC]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476110(v=vs.85).aspx +/// This structure describes the depth stencil state which is used in a call to +/// IRenderDevice::CreateDepthStencilState() and generally mirrows [D3D11_DEPTH_STENCIL_DESC][] +/// structure. +struct DepthStencilStateDesc : DeviceObjectAttribs +{ + /// Enable depth-stencil operations. When it is set to False, + /// depth test always passes, depth writes are disabled, + /// and no stencil operations are performed + Bool DepthEnable; + + /// Enable or disable writes to a depth buffer + Bool DepthWriteEnable; + + /// A function that compares depth data against existing depth data. + /// See Diligent::COMPARISON_FUNCTION for details. + COMPARISON_FUNCTION DepthFunc; + + /// Enable stencil opertaions. + Bool StencilEnable; + + /// Identify which bits of the depth-stencil buffer are accessed when reading stencil data. + Uint8 StencilReadMask; + + /// Identify which bits of the depth-stencil buffer are accessed when writing stencil data. + Uint8 StencilWriteMask; + + /// Identify stencil operations for the front-facing triangles, see Diligent::StencilOpDesc. + StencilOpDesc FrontFace; + + /// Identify stencil operations for the back-facing triangles, see Diligent::StencilOpDesc. + StencilOpDesc BackFace; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// --------------------|-------------- + /// DepthEnable | True + /// DepthWriteEnable | True + /// DepthFunc | COMPARISON_FUNC_LESS + /// StencilEnable | False + /// StencilReadMask | 0xFF + /// StencilWriteMask | 0xFF + /// + /// Members of FrontFace and BackFace + /// are initialized by StencilOpDesc::StencilOpDesc() + DepthStencilStateDesc() : + DepthEnable ( True ), + DepthWriteEnable( True ), + DepthFunc ( COMPARISON_FUNC_LESS ), + StencilEnable ( False ), + StencilReadMask ( 0xFF ), + StencilWriteMask( 0xFF ) + {} + + /// Tests if two structures are equivalent + + /// \param [in] rhs - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise + /// \remarks + /// The operator ignores DeviceObjectAttribs::Name field as it does not affect + /// the depth-stencil state. + bool operator == (const DepthStencilStateDesc& rhs)const + { + // Name is primarily used for debug purposes and does not affect the state. + // It is ignored in comparison operation. + return // strcmp(Name, rhs.Name) == 0 && + DepthEnable == rhs.DepthEnable && + DepthWriteEnable == rhs.DepthWriteEnable && + DepthFunc == rhs.DepthFunc && + StencilEnable == rhs.StencilEnable && + StencilReadMask == rhs.StencilReadMask && + StencilWriteMask == rhs.StencilWriteMask && + FrontFace == rhs.FrontFace && + BackFace == rhs.BackFace; + } +}; + +/// Depth stencil state interface + +/// The interface holds the depth-stencil state that can be bound to the pipeline by a call +/// to IDeviceContext::SetDepthStencilState(). To create a depth-stencil state, call +/// IRenderDevice::CreateDepthStencilState(). +class IDepthStencilState : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the depth stencil state description used to create the object + virtual const DepthStencilStateDesc& GetDesc()const = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/DeviceCaps.h b/Graphics/GraphicsEngine/interface/DeviceCaps.h new file mode 100644 index 00000000..3d8284ed --- /dev/null +++ b/Graphics/GraphicsEngine/interface/DeviceCaps.h @@ -0,0 +1,129 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the device capabilities + +#include "GraphicsTypes.h" + +namespace Diligent +{ + /// Device type + enum class DeviceType : Int32 + { + Undefined = 0, ///< Undefined device + DirectX, ///< DirectX device + OpenGL, ///< OpenGL device + OpenGLES ///< OpenGLES device + }; + + /// Texture sampler capabilities + struct SamplerCaps + { + /// Indicates if device supports border texture addressing mode + Bool bBorderSamplingModeSupported; + + /// Indicates if device supports anisotrpoic filtering + Bool bAnisotropicFilteringSupported; + + /// Indicates if device supports MIP load bias + Bool bLODBiasSupported; + + /// Initializes the structure members with default values + SamplerCaps() : + bBorderSamplingModeSupported( True ), + bAnisotropicFilteringSupported( True ), + bLODBiasSupported( True ) + {} + }; + + /// Texture capabilities + struct TextureCaps + { + /// Indicates if device supports 1D textures + Bool bTexture1DSupported; + + /// Indicates if device supports 1D texture arrays + Bool bTexture1DArraySupported; + + /// Indicates if device supports 2D multisampled textures + Bool bTexture2DMSSupported; + + /// Indicates if device supports 2D multisampled texture arrays + Bool bTexture2DMSArraySupported; + + /// Indicates if device supports texture views + bool bTextureViewSupported; + + /// Initializes the structure members with default values + TextureCaps(): + bTexture1DSupported( True ), + bTexture1DArraySupported( True ), + bTexture2DMSSupported( True ), + bTexture2DMSArraySupported( True ), + bTextureViewSupported( True ) + {} + }; + + /// Device capabilities + struct DeviceCaps + { + /// Device type. See Diligent::DeviceType. + DeviceType DevType; + + /// Major API revision. For instance, for D3D11.2 this value would be 11, + /// and for OpenGL4.3 this value would be 4. + Int32 MajorVersion; + + /// Major API revision. For instance, for D3D11.2 this value would be 2, + /// and for OpenGL4.3 this value would be 3. + Int32 MinorVersion; + + /// Indicates if device supports separable programs + Bool bSeparableProgramSupported; + + /// Indicates if device supports indirect draw commands + Bool bIndirectRenderingSupported; + + /// Indicates if device supports wireframe fill mode + Bool bWireframeFillSupported; + + /// Texture sampling capabilities. See Diligent::SamplerCaps. + SamplerCaps SamCaps; + + /// Texture capabilities. See Diligent::TextureCaps. + TextureCaps TexCaps; + + /// Initializes the structure members with default values + DeviceCaps() : + DevType( DeviceType::Undefined ), + MajorVersion( 0 ), + MinorVersion( 0 ), + bSeparableProgramSupported( True ), + bIndirectRenderingSupported( True ), + bWireframeFillSupported( True ) + {} + }; +} diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h new file mode 100644 index 00000000..c1998091 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -0,0 +1,510 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IDeviceContext interface and related data structures + +#include "Object.h" +#include "DeviceCaps.h" +#include "Constants.h" +#include "Buffer.h" +#include "VertexDescription.h" +#include "Shader.h" +#include "Texture.h" +#include "Sampler.h" +#include "ResourceMapping.h" +#include "TextureView.h" +#include "BufferView.h" +#include "DepthStencilState.h" +#include "BlendState.h" + +namespace Diligent +{ + +// {DC92711B-A1BE-4319-B2BD-C662D1CC19E4} +static const Diligent::INTERFACE_ID IID_DeviceContext = +{ 0xdc92711b, 0xa1be, 0x4319, { 0xb2, 0xbd, 0xc6, 0x62, 0xd1, 0xcc, 0x19, 0xe4 } }; + +/// Input primitive topology. + +/// This enumeration is used by DrawAttribs structure to define input primitive topology. +enum PRIMITIVE_TOPOLOGY : Int32 +{ + /// Undefined topology + PRIMITIVE_TOPOLOGY_UNDEFINED = 0, + + /// Interpret the vertex data as a list of triangles.\n + /// D3D11 counterpart: D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST. OpenGL counterpart: GL_TRIANGLES. + PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + + /// Interpret the vertex data as a triangle strip.\n + /// D3D11 counterpart: D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP. OpenGL counterpart: GL_TRIANGLE_STRIP. + PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + + /// Interpret the vertex data as a list of points.\n + /// D3D11 counterpart: D3D11_PRIMITIVE_TOPOLOGY_POINTLIST. OpenGL counterpart: GL_POINTS. + PRIMITIVE_TOPOLOGY_POINT_LIST, + + /// Interpret the vertex data as a list of lines.\n + /// D3D11 counterpart: D3D11_PRIMITIVE_TOPOLOGY_LINELIST. OpenGL counterpart: GL_LINES. + PRIMITIVE_TOPOLOGY_LINE_LIST, + + /// Helper value that stores the total number of topologies in the enumeration + PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES +}; + +/// Defines the draw command attributes + +/// This structure is used by IRenderDevice::Draw() +struct DrawAttribs +{ + /// Input primitive topology, see Diligent::PRIMITIVE_TOPOLOGY. + PRIMITIVE_TOPOLOGY Topology; + union + { + /// For a non-indexed draw call, number of vertices to draw + Uint32 NumVertices; + + /// For an indexed draw call, number of indices to draw + Uint32 NumIndices; + }; + /// For an indexed draw call, type of elements in the index buffer. + /// Allowed values: VT_UINT16 and VT_UINT32. Ignored if DrawAttribs::IsIndexed is False. + VALUE_TYPE IndexType; + + /// Indicates if index buffer will be used to index input vertices + Bool IsIndexed; + + /// Number of instances to draw. If more than one instance is specified, + /// instanced draw call will be performed. + Uint32 NumInstances; + + /// Indicates if indirect draw call will be performed. If set to True, + /// pIndirectDrawAttribs must contain valid pointer to the buffer, from which + /// draw attributes will be read. + Bool IsIndirect; + + /// For indexed rendering, a constant which is added to each index before + /// accessing the vertex buffer. + Uint32 BaseVertex; + + /// For indirect rendering, offset from the beginning of the buffer to the + /// location of draw command attributes. Ignored if DrawAttribs::IsIndirect is False. + Uint32 IndirectDrawArgsOffset; + + union + { + /// For non-indexed rendering, LOCATION (or INDEX, but NOT the byte offset) of the + /// first vertex in the vertex buffer to start reading vertices from + Uint32 StartVertexLocation; + + /// For indexed rendering, LOCATION (NOT the byte offset) of the first index in + /// the index buffer to start reading indices from + Uint32 FirstIndexLocation; + }; + /// For instanced rendering, LOCATION (or INDEX, but NOT the byte offset) in the vertex + /// buffer to start reading instance data from + Uint32 FirstInstanceLocation; + + /// For indirect rendering, pointer to the buffer, from which + /// draw attributes will be read. Ignored if DrawAttribs::IsIndirect is False. + IBuffer *pIndirectDrawAttribs; + + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// ------------------------|-------------- + /// Topology | PRIMITIVE_TOPOLOGY_UNDEFINED + /// NumVertices | 0 + /// IndexType | VT_UNDEFINED + /// IsIndexed | False + /// NumInstances | 1 + /// IsIndirect | False + /// BaseVertex | 0 + /// IndirectDrawArgsOffset | 0 + /// StartVertexLocation | 0 + /// FirstInstanceLocation | 0 + /// pIndirectDrawAttribs | nullptr + DrawAttribs() : + Topology(PRIMITIVE_TOPOLOGY_UNDEFINED), + NumVertices(0), + IndexType(VT_UNDEFINED), + IsIndexed(False), + NumInstances(1), + IsIndirect(False), + BaseVertex(0), + IndirectDrawArgsOffset(0), + StartVertexLocation(0), + FirstInstanceLocation(0), + pIndirectDrawAttribs(nullptr) + {} +}; + +/// Defines which parts of the depth-stencil buffer to clear. + +/// These flags are used by IDeviceContext::ClearDepthStencil(). +enum CLEAR_DEPTH_STENCIL_FLAGS : Int32 +{ + CLEAR_DEPTH_FLAG = 0x01, ///< Clear depth part of the buffer + CLEAR_STENCIL_FLAG = 0x02 ///< Clear stencil part of the buffer +}; + +/// Describes dispatch command arguments. + +/// [Dispatch]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476405(v=vs.85).aspx +/// This structure is used by IDeviceContext::DispatchCompute(). +/// See [ID3D11DeviceContext::Dispatch on MSDN][Dispatch] for details. +struct DispatchComputeAttribs +{ + Uint32 ThreadGroupCountX; ///< Number of groups dispatched in X direction. + Uint32 ThreadGroupCountY; ///< Number of groups dispatched in Y direction. + Uint32 ThreadGroupCountZ; ///< Number of groups dispatched in Z direction. + + /// Pointer to the buffer containing dispatch arguments. + /// If not nullptr, then indirect dispatch command is executed, and + /// ThreadGroupCountX, ThreadGroupCountY, and ThreadGroupCountZ are ignored + IBuffer *pIndirectDispatchAttribs; + + /// If pIndirectDispatchAttribs is not nullptr, indicates offset from the beginning + /// of the buffer to the dispatch command arguments. Ignored otherwise + Uint32 DispatchArgsByteOffset; + + /// Initializes the structure to perform non-indirect dispatch command + + /// \param [in] GroupsX - Number of groups dispatched in X direction. Default value is 1. + /// \param [in] GroupsY - Number of groups dispatched in Y direction. Default value is 1. + /// \param [in] GroupsZ - Number of groups dispatched in Z direction. Default value is 1. + DispatchComputeAttribs( Uint32 GroupsX = 1, Uint32 GroupsY = 1, Uint32 GroupsZ = 1 ) : + ThreadGroupCountX( GroupsX ), + ThreadGroupCountY( GroupsY ), + ThreadGroupCountZ( GroupsZ ), + pIndirectDispatchAttribs(nullptr), + DispatchArgsByteOffset(0) + {} + + /// Initializes the structure to perform indirect dispatch command + + /// \param [in] pDispatchAttribs - Pointer to the buffer containing dispatch arguments. + /// \param [in] Offset - Offset from the beginning of the buffer to the dispatch command + /// arguments. Default value is 0. + DispatchComputeAttribs( IBuffer *pDispatchAttribs, Uint32 Offset = 0 ) : + ThreadGroupCountX( 0 ), + ThreadGroupCountY( 0 ), + ThreadGroupCountZ( 0 ), + pIndirectDispatchAttribs( pDispatchAttribs ), + DispatchArgsByteOffset( Offset ) + {} +}; + +/// Defines allowed flags for IDeviceContext::SetVertexBuffers() function. +enum SET_VERTEX_BUFFERS_FLAGS : Int32 +{ + /// Reset the vertex buffers to only the buffers specified in this + /// call. All buffers previously bound to the pipeline will be unbound. + SET_VERTEX_BUFFERS_FLAG_RESET = 0x01 +}; + +/// Describes the viewport. + +/// This structure is used by IDeviceContext::SetViewports(). +struct Viewport +{ + /// X coordinate of the left boundary of the viewport. + Float32 TopLeftX; + + /// Y coordinate of the top boundary of the viewport. + /// When defining a viewport, DirectX convention is used: + /// window coordinate systems originates in the LEFT TOP corner + /// of the screen with Y axis pointing down. + Float32 TopLeftY; + + /// Viewport width + Float32 Width; + + /// Viewport Height + Float32 Height; + + /// Minimum depth of the viewport. Ranges between 0 and 1. + Float32 MinDepth; + + /// Maximum depth of the viewport. Ranges between 0 and 1. + Float32 MaxDepth; + + /// Initializes the structure + Viewport(Float32 _TopLeftX = 0, Float32 _TopLeftY = 0, + Float32 _Width = 0, Float32 _Height = 0, + Float32 _MinDepth = 0, Float32 _MaxDepth = 1 ) + : + TopLeftX( _TopLeftX ), + TopLeftY( _TopLeftY ), + Width ( _Width ), + Height ( _Height ), + MinDepth( _MinDepth ), + MaxDepth( _MaxDepth ) + {} +}; + +/// Describes the rectangle. + +/// This structure is used by IDeviceContext::SetScissorRects(). +/// +/// \remarks When defining a viewport, Windows convention is used: +/// window coordinate systems originates in the LEFT TOP corner +/// of the screen with Y axis pointing down. +struct Rect +{ + Int32 left; ///< X coordinate of the left boundary of the viewport. + Int32 top; ///< Y coordinate of the top boundary of the viewport. + Int32 right; ///< X coordinate of the right boundary of the viewport. + Int32 bottom;///< Y coordinate of the bottom boundary of the viewport. + + /// Initializes the structure + Rect( Int32 _left = 0, Int32 _top = 0, Int32 _right = 0, Int32 _bottom = 0 ) : + left ( _left ), + top ( _top ), + right ( _right ), + bottom( _bottom ) + {} +}; + + +/// Device context interface + +/// \remarks Device context keeps strong references to all objects currently bound to +/// the pipeline: buffers, states, samplers, shaders, etc. +/// The context also keeps strong reference to the device and +/// the swap chain. +class IDeviceContext : public IObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Binds shaders to the pipeline + + /// \param [in] ppShaders - Array of pointers to IShader interface. + /// \param [in] NumShadersToSet - Number of shaders to bind. + /// \remarks All shaders must be set atomically. All shaders that are not specified + /// in a call to SetShaders() will be unbound.\n + /// The device context keeps strong references to all bound shaders. + /// Thus a shader cannot be released until it is unbound from the context. + virtual void SetShaders(IShader **ppShaders, Uint32 NumShadersToSet) = 0; + + /// Binds resources for all shaders bound to the pipeline + + /// \param [in] pResourceMapping - Pointer to the resource mapping interface. + /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. + /// \remarks This function is intended to be used with older OpenGL devices that + /// do not support program pipelines (OpenGL4.1-, OpenGLES3.0-).\n + /// The function should be called AFTER all the required shaders are bound to the + /// context. It should also be called for every shader combination. + virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) = 0; + + + /// Binds vertex buffers to the pipeline. + + /// \param [in] StartSlot - The first input slot for binding. The first vertex buffer is + /// explicitly bound to the start slot; each additional vertex buffer + /// in the array is implicitly bound to each subsequent input slot. + /// \param [in] NumBuffersSet - The number of vertex buffers in the array. + /// \param [in] ppBuffers - A pointer to an array of vertex buffers. + // The vertex buffers must have been created with the Diligent::BIND_VERTEX_BUFFER flag. + /// \param [in] pStrides - Pointer to an array of stride values; one stride value for each buffer + /// in the vertex-buffer array. Each stride is the size (in bytes) of the + /// elements that are to be used from that vertex buffer. + /// If this parameter is nullptr, tight strides from the input layout + /// will be used for each buffer. See IVertexDescription::GetTightStrides(). + /// \param [in] pOffsets - Pointer to an array of offset values; one offset value for each buffer + /// in the vertex-buffer array. Each offset is the number of bytes between + /// the first element of a vertex buffer and the first element that will be + /// used. If this parameter is nullptr, zero offsets for all buffers will be used. + /// \param [in] Flags - Additional flags for the operation. See Diligent::SET_VERTEX_BUFFERS_FLAGS + /// for a list of allowed values. + /// \remarks The device context keeps strong references to all bound vertex buffers. + /// Thus a buffer cannot be released until it is unbound from the context.\n + /// It is suggested to specify Diligent::SET_VERTEX_BUFFERS_FLAG_RESET flag + /// whenever possible. This will assure that no buffers from previous draw calls are + /// are bound to the pipeline. + virtual void SetVertexBuffers(Uint32 StartSlot, + Uint32 NumBuffersSet, + IBuffer **ppBuffers, + Uint32 *pStrides, + Uint32 *pOffsets, + Uint32 Flags) = 0; + + /// Clears the context state. + virtual void ClearState() = 0; + + /// Sets vertex description + + /// \param [in] pVertexDesc - Pointer to IVertexDescription interface that describes + /// how to read data from input vertex buffers. + /// \remarks The device context keeps strong reference to the vertex description. + /// Thus a vertex description object cannot be released until it is unbound + /// from the context. + virtual void SetVertexDescription(IVertexDescription *pVertexDesc) = 0; + + /// Binds an index buffer to the pipeline + + /// \param [in] pIndexBuffer - Pointer to the index buffer. The buffer must have been created + /// with the Diligent::BIND_INDEX_BUFFER flag. + /// \param [in] ByteOffset - Offset from the beginning of the buffer to + /// the start of index data. + /// \remarks The device context keeps strong reference to the index buffer. + /// Thus an index buffer object cannot be released until it is unbound + /// from the context. + virtual void SetIndexBuffer(IBuffer *pIndexBuffer, Uint32 ByteOffset) = 0; + + + /// Sets the depth stencil state + + /// \param [in] pDepthStencilState - Pointer to the IDepthStencilState interface holding the state + /// \param [in] StencilRef - Stencil reference value used in stencil operations. + /// See DepthStencilStateDesc. + /// \remarks The device context keeps strong reference to the bound depth-stencil state. + /// Thus a depth-stencil state object cannot be released until it is unbound + /// from the context. + virtual void SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef = 0 ) = 0; + + /// Sets the rasterizer state + + /// \param [in] pRS - Pointer to the IRasterizerState interface holding the state + /// \remarks The device context keeps strong reference to the bound rasterizer state. + /// Thus a rasterizer state object cannot be released until it is unbound + /// from the context. + virtual void SetRasterizerState( IRasterizerState *pRS ) = 0; + + /// Sets the blend state + + /// \param [in] pBS - Pointer to the IBlendState interface holding the state + /// \param [in] pBlendFactors - Array of four blend factors, one for each RGBA component. + /// Theses factors are used if the blend state uses one of the + /// Diligent::BLEND_FACTOR_BLEND_FACTOR or + /// Diligent::BLEND_FACTOR_INV_BLEND_FACTOR + /// blend factors. If nullptr is provided, + /// default blend factors array {1,1,1,1} will be used. + /// \param [in] SampleMask - 32-bit sample mask that determines which samples get updated + /// in all the active render targets. A sample mask is always applied; + /// it is independent of whether multisampling is enabled, and does not + /// depend on whether an application uses multisample render targets. + /// \remarks The device context keeps strong reference to the bound blend state. + /// Thus a blend state object cannot be released until it is unbound + /// from the context. + virtual void SetBlendState( IBlendState *pBS, const float* pBlendFactors = nullptr, Uint32 SampleMask = 0xFFFFFFFF ) = 0; + + /// Sets an array of viewports + + /// \param [in] NumViewports - Number of viewports to set. + /// \param [in] pViewports - An array of Viewport structures describing the viewports to bind. + /// \param [in] RTWidth - Render target width. If 0 is provided, width of the currently bound render target will be used. + /// \param [in] RTHeight- Render target height. If 0 is provided, height of the currently bound render target will be used. + /// \remarks + /// DirectX and OpenGL use different window coordinate systems. In DirectX, the coordinate system origin + /// is in the left top corner of the screen with Y axis pointing down. In OpenGL, the origin + /// is in the left bottom corener of the screen with Y axis pointing up. Render target size is + /// required to convert viewport from DirectX to OpenGL coordinate system if OpenGL device is used.\n\n + /// All viewports must be set atomically as one operation. Any viewports not + /// defined by the call are disabled.\n\n + /// You can set the viewport size to match the currently bound render target using the + /// following call: + /// + /// pContext->SetViewports(1, nullptr, 0, 0); + virtual void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight ) = 0; + + /// Sets active scissor rects + + /// \param [in] NumRects - Number of scissor rectangles to set. + /// \param [in] pRects - An array of Rect structures describing the scissor rectangles to bind. + /// \param [in] RTWidth - Render target width. If 0 is provided, width of the currently bound render target will be used. + /// \param [in] RTHeight - Render target height. If 0 is provided, height of the currently bound render target will be used. + /// \remarks + /// DirectX and OpenGL use different window coordinate systems. In DirectX, the coordinate system origin + /// is in the left top corner of the screen with Y axis pointing down. In OpenGL, the origin + /// is in the left bottom corener of the screen with Y axis pointing up. Render target size is + /// required to convert viewport from DirectX to OpenGL coordinate system if OpenGL device is used.\n\n + /// All scissor rects must be set atomically as one operation. Any rects not + /// defined by the call are disabled. + virtual void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight ) = 0; + + /// Binds one or more render targets and the depth-stencil buffer to the pipeline. It also + /// sets the viewport to match the first non-null render target or depth-stencil buffer. + + /// \param [in] NumRenderTargets - Number of render targets to bind. + /// \param [in] ppRenderTargets - Array of pointers to ITextureView that represent the render + /// targets to bind to the device. The type of each view in the + /// array must be Diligent::TEXTURE_VIEW_RENDER_TARGET. + /// \param [in] pDepthStencil - Pointer to the ITextureView that represents the depth stencil to + /// bind to the device. The view type must be + /// Diligent::TEXTURE_VIEW_DEPTH_STENCIL. + /// \remarks + /// The device context will keep strong references to all bound render target + /// and depth-stencil views. Thus these views (and consequently referenced textures) + /// cannot be released until they are unbound from the context.\n + /// Any render targets not defined by this call are set to nullptr.\n\n + /// You can set the default render target and depth stencil using the + /// following call: + /// + /// pContext->SetRenderTargets(0, nullptr, nullptr); + virtual void SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil ) = 0; + + /// Executes a draw command + + /// \param [in] DrawAttribs - Structure describing draw command attributes, see DrawAttribs for details. + virtual void Draw(DrawAttribs &DrawAttribs) = 0; + + /// Executes a dispatch compute command + + /// \param [in] DispatchAttrs - Structure describing dispatch command attributes, + /// see DispatchComputeAttribs for details. + virtual void DispatchCompute( const DispatchComputeAttribs &DispatchAttrs ) = 0; + + /// Clears a depth-stencil view + + /// \param [in] pView - Pointer to ITextureView interface to clear. The view type must be + /// Diligent::TEXTURE_VIEW_DEPTH_STENCIL. + /// \param [in] ClearFlags - Idicates which parts of the buffer to clear, see Diligent::CLEAR_DEPTH_STENCIL_FLAGS. + /// \param [in] fDepth - Value to clear depth part of the view with. + /// \param [in] Stencil - Value to clear stencil part of the view with. + /// \remarks The full extent of the view is always cleared. Viewport and scissor settings are not applied. + /// \note The depth-stencil view must be bound to the pipeline for clear operation to be performed. + virtual void ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags = CLEAR_DEPTH_FLAG, float fDepth = 1.f, Uint8 Stencil = 0 ) = 0; + + /// Clears a render target view + + /// \param [in] pView - Pointer to ITextureView interface to clear. The view type must be + /// Diligent::TEXTURE_VIEW_RENDER_TARGET. + /// \param [in] RGBA - A 4-component array that represents the color to fill the render target with. + /// If nullptr is provided, the default array {0,0,0,0} will be used. + /// \remarks The full extent of the view is always cleared. Viewport and scissor settings are not applied. + /// \note The render target view must be bound to the pipeline for clear operation to be performed. + virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA = nullptr ) = 0; + + /// Flushes the command buffer + virtual void Flush() = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/DeviceObject.h b/Graphics/GraphicsEngine/interface/DeviceObject.h new file mode 100644 index 00000000..6a3cde70 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/DeviceObject.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Defines Diligent::IDeviceObject interface + +#include "Object.h" +#include "GraphicsTypes.h" + +namespace Diligent +{ + +// {5B4CCA0B-5075-4230-9759-F48769EE5502} +static const Diligent::INTERFACE_ID IID_DeviceObject = +{ 0x5b4cca0b, 0x5075, 0x4230, { 0x97, 0x59, 0xf4, 0x87, 0x69, 0xee, 0x55, 0x2 } }; + +/// Base interface for all objects created by the render device Diligent::IRenderDevice +class IDeviceObject : public IObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the buffer object description + virtual const DeviceObjectAttribs& GetDesc()const = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h new file mode 100644 index 00000000..4f8bbcba --- /dev/null +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -0,0 +1,1087 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Contains basic graphics engine type defintions + +#include "BasicTypes.h" + +/// Graphics engine namespace +namespace Diligent +{ + /// Value type + + /// This enumeration describes value type. It is used by + /// - BufferDesc structure to describe value type of a formatted buffer + /// - DrawAttribs structure to describe index type for an indexed draw call + enum VALUE_TYPE : Int32 + { + VT_UNDEFINED = 0, ///< Undefined type + VT_INT8, ///< Signed 8-bit integer + VT_INT16, ///< Signed 16-bit integer + VT_INT32, ///< Signed 32-bit integer + VT_UINT8, ///< Unsigned 8-bit integer + VT_UINT16, ///< Unsigned 16-bit integer + VT_UINT32, ///< Unsigned 32-bit integer + VT_FLOAT16, ///< Half-precision 16-bit floating point + VT_FLOAT32, ///< Full-precision 32-bit floating point + VT_NUM_TYPES ///< Helper value storing total number of types in the enumeration + }; + + /// Resource binding flags + + /// [D3D11_BIND_FLAG]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476085(v=vs.85).aspx + /// + /// This enumeration describes which parts of the pipeline a resource can be bound to. + /// It generally mirrows [D3D11_BIND_FLAG][] enumeration. It is used by + /// - BufferDesc to describe bind flags for a buffer + /// - TextureDesc to describe bind flags for a texture + enum BIND_FLAGS : Int32 + { + BIND_NONE = 0x0L, ///< Undefined binding + BIND_VERTEX_BUFFER = 0x1L, ///< A buffer can be bound as a vertex buffer + BIND_INDEX_BUFFER = 0x2L, ///< A buffer can be bound as an index buffer + BIND_UNIFORM_BUFFER = 0x4L, ///< A buffer can be bound as a uniform buffer + /// \warning This flag may not be combined with any other bind flag + BIND_SHADER_RESOURCE = 0x8L, ///< A buffer or a texture can be bound as a shader resource + /// \warning This flag cannot be used with MAP_WRITE_NO_OVERWRITE flag + BIND_STREAM_OUTPUT = 0x10L,///< A buffer can be bound as a target for stream output stage + BIND_RENDER_TARGET = 0x20L,///< A texture can be bound as a render target + BIND_DEPTH_STENCIL = 0x40L,///< A texture can be bound as a depth-stencil target + BIND_UNORDERED_ACCESS = 0x80L,///< A buffer or a texture can be bound as an unordered access view + BIND_INDIRECT_DRAW_ARGS = 0x100L///< A buffer can be bound as the source buffer for indirect draw commands + }; + + /// Resource usage + + /// [D3D11_USAGE]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476259(v=vs.85).aspx + /// This enumeration describes expected resource usage. It generally mirrows [D3D11_USAGE] enumeration. + /// The enumeration is used by + /// - BufferDesc to describe usage for a buffer + /// - TextureDesc to describe usage for a texture + enum USAGE : Int32 + { + /// A resource that can only be read by the GPU. It cannot be written by the GPU, + /// and cannot be accessed at all by the CPU. This type of resource must be initialized + /// when it is created, since it cannot be changed after creation. \n + /// D3D11 Counterpart: D3D11_USAGE_IMMUTABLE. OpenGL counterpart: GL_STATIC_DRAW + USAGE_STATIC = 0, + + /// A resource that requires read and write access by the GPU and can also be occasionally + /// written by the CPU. \n + /// D3D11 Counterpart: D3D11_USAGE_DEFAULT. OpenGL counterpart: GL_DYNAMIC_DRAW + USAGE_DEFAULT, + + /// A resource that can be read by the GPU and written at least once per frame by the CPU. \n + /// D3D11 Counterpart: D3D11_USAGE_DYNAMIC. OpenGL counterpart: GL_STREAM_DRAW + USAGE_DYNAMIC, + + /// A resource that facilitates transferring data from GPU to CPU. \n + /// D3D11 Counterpart: D3D11_USAGE_STAGING. OpenGL counterpart: GL_DYNAMIC_READ + USAGE_CPU_ACCESSIBLE + }; + + /// Allowed CPU access mode flags when mapping a resource + + /// The enumeration is used by + /// - BufferDesc to describe CPU access mode for a buffer + /// - TextureDesc to describe CPU access mode for a texture + /// \note Only USAGE_DYNAMIC resources can be mapped + enum CPU_ACCESS_FLAG : Int32 + { + CPU_ACCESS_READ = 0x01, ///< A resource can be mapped for reading + CPU_ACCESS_WRITE = 0x02 ///< A resource can be mapped for writing + }; + + /// Resource mapping type + + /// [D3D11_MAP]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476181(v=vs.85).aspx + /// Describes how a mapped resource will be accessed. This enumeration generally + /// mirrows [D3D11_MAP][] enumeration. It is used by + /// - IBuffer::Map to describe buffer mapping type + /// - ITexture::Map to describe texture mapping type + enum MAP_TYPE : Int32 + { + /// Resource is mapped for reading. \n + /// D3D11 counterpart: D3D11_MAP_READ. OpenGL counterpart: GL_MAP_READ_BIT + MAP_READ = 0, + + /// Resource is mapped for writing. \n + /// D3D11 counterpart: D3D11_MAP_WRITE. OpenGL counterpart: GL_MAP_WRITE_BIT + MAP_WRITE, + + /// Resource is mapped for reading and writing. \n + /// D3D11 counterpart: D3D11_MAP_READ_WRITE. OpenGL counterpart: GL_MAP_WRITE_BIT | GL_MAP_READ_BIT + MAP_READ_WRITE, + + /// Resource is mapped for writing; the previous contents of the resource will be undefined. \n + /// D3D11 counterpart: D3D11_MAP_WRITE_DISCARD. OpenGL counterpart: GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT + /// \note OpenGL implementation may orphan a buffer instead + MAP_WRITE_DISCARD, + + /// Resource is mapped for writing; the existing contents of the resource cannot be overwritten. \n + /// D3D11 counterpart: D3D11_MAP_WRITE_NO_OVERWRITE. OpenGL counterpart: GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT + MAP_WRITE_NO_OVERWRITE + }; + + /// Special map flags + + /// Describes special arguments for a map operation. + /// This enumeration is used by + /// - IBuffer::Map to describe buffer mapping flags + /// - ITexture::Map to describe texture mapping flags + enum MAP_FLAGS : Int32 + { + /// Specifies that map operation should not wait until previous command that + /// using the same resource completes. Map returns null pointer if the resource + /// is still in use.\n + /// D3D11 counterpart: D3D11_MAP_FLAG_DO_NOT_WAIT + /// \note: OpenGL does not have corresponding flag, so a buffer will always be mapped + MAP_FLAG_DO_NOT_WAIT = 0x001 + }; + + /// Describes texture type + + /// This enumeration is used by + /// - TextureDesc to describe texture type + /// - TextureViewDesc to describe texture view type + enum TEXTURE_TYPE : Int32 + { + TEXTURE_TYPE_UNDEFINED = 0, ///< Texture type undefined + TEXTURE_TYPE_1D, ///< One-dimensional texture + TEXTURE_TYPE_1D_ARRAY, ///< One-dimensional texture array + TEXTURE_TYPE_2D, ///< Two-dimensional texture + TEXTURE_TYPE_2D_ARRAY, ///< Two-dimensional texture array + TEXTURE_TYPE_3D, ///< Three-dimensional texture + TEXTURE_TYPE_CUBE, ///< Cube-map texture + TEXTURE_TYPE_CUBE_ARRAY, ///< Cube-map array texture + TEXTURE_TYPE_NUM_TYPES ///< Helper value that stores the total number of texture types in the enumeration + }; + + /// Texture view type + + /// This enumeration describes allowed view types for a texture view. It is used by TextureViewDesc + /// structure. + enum TEXTURE_VIEW_TYPE : Int32 + { + /// Undefined view type + TEXTURE_VIEW_UNDEFINED = 0, + + /// A texture view will define a shader resource view that will be used + /// as the source for the shader read operations + TEXTURE_VIEW_SHADER_RESOURCE, + + /// A texture view will define a render target view that will be used + /// as the target for rendering operations + TEXTURE_VIEW_RENDER_TARGET, + + /// A texture view will define a depth stencil view that will be used + /// as the target for rendering operations + TEXTURE_VIEW_DEPTH_STENCIL, + + /// A texture view will define an unordered access view that will be used + /// for unordered read/write operations from the shaders + TEXTURE_VIEW_UNORDERED_ACCESS, + + /// Helper value that stores that total number of texture views + TEXTURE_VIEW_NUM_VIEWS + }; + + /// Buffer view type + + /// This enumeration describes allowed view types for a buffer view. It is used by BufferViewDesc + /// structure. + enum BUFFER_VIEW_TYPE : Int32 + { + /// Undefined view type + BUFFER_VIEW_UNDEFINED = 0, + + /// A buffer view will define a shader resource view that will be used + /// as the source for the shader read operations + BUFFER_VIEW_SHADER_RESOURCE, + + /// A buffer view will define an unordered access view that will be used + /// for unordered read/write operations from the shaders + BUFFER_VIEW_UNORDERED_ACCESS, + + /// Helper value that stores that total number of buffer views + BUFFER_VIEW_NUM_VIEWS + }; + + /// Texture formats + + /// This enumeration describes available texture formats and generally mirrows DXGI_FORMAT enumeration. + /// The table below provides detailed information on each format. Most of the formats are widely supported + /// by all modern APIs (DX10+, OpenGL3.3+ and OpenGLES3.0+). Specific requirements are additionally indicated. + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb173059(v=vs.85).aspx">DXGI_FORMAT enumeration on MSDN</a>, + /// <a href = "https://www.opengl.org/wiki/Image_Format">OpenGL Texture Formats</a> + /// + enum TEXTURE_FORMAT : Int32 + { + /// Unknown format + TEX_FORMAT_UNKNOWN = 0, + + /// Four-component 128-bit typeless format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32B32A32_TYPELESS. OpenGL does not have direct counterpart, GL_RGBA32F is used. + TEX_FORMAT_RGBA32_TYPELESS, + + /// Four-component 128-bit floating-point format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32B32A32_FLOAT. OpenGL counterpart: GL_RGBA32F. + TEX_FORMAT_RGBA32_FLOAT, + + /// Four-component 128-bit unsigned-integer format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32B32A32_UINT. OpenGL counterpart: GL_RGBA32UI. + TEX_FORMAT_RGBA32_UINT, + + /// Four-component 128-bit signed-integer format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32B32A32_SINT. OpenGL counterpart: GL_RGBA32I. + TEX_FORMAT_RGBA32_SINT, + + /// Three-component 96-bit typeless format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32B32_TYPELESS. OpenGL does not have direct counterpart, GL_RGB32F is used. + /// \warning This format has weak hardware support and is not recommended + TEX_FORMAT_RGB32_TYPELESS, + + /// Three-component 96-bit floating-point format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32B32_FLOAT. OpenGL counterpart: GL_RGB32F. + /// \warning This format has weak hardware support and is not recommended + TEX_FORMAT_RGB32_FLOAT, + + /// Three-component 96-bit unsigned-integer format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32B32_UINT. OpenGL counterpart: GL_RGB32UI. + /// \warning This format has weak hardware support and is not recommended + TEX_FORMAT_RGB32_UINT, + + /// Three-component 96-bit signed-integer format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32B32_SINT. OpenGL counterpart: GL_RGB32I. + /// \warning This format has weak hardware support and is not recommended + TEX_FORMAT_RGB32_SINT, + + /// Four-component 64-bit typeless format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16B16A16_TYPELESS. OpenGL does not have direct counterpart, GL_RGBA16F is used. + TEX_FORMAT_RGBA16_TYPELESS, + + /// Four-component 64-bit half-precision floating-point format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16B16A16_FLOAT. OpenGL counterpart: GL_RGBA16F. + TEX_FORMAT_RGBA16_FLOAT, + + /// Four-component 64-bit unsigned-normalized-integer format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16B16A16_UNORM. OpenGL counterpart: GL_RGBA16. \n + /// [GL_EXT_texture_norm16]: https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_norm16.txt + /// OpenGLES: [GL_EXT_texture_norm16][] extension is required + TEX_FORMAT_RGBA16_UNORM, + + /// Four-component 64-bit unsigned-integer format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16B16A16_UINT. OpenGL counterpart: GL_RGBA16UI. + TEX_FORMAT_RGBA16_UINT, + + /// [GL_EXT_texture_norm16]: https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_norm16.txt + /// Four-component 64-bit signed-normalized-integer format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16B16A16_SNORM. OpenGL counterpart: GL_RGBA16_SNORM. \n + /// [GL_EXT_texture_norm16]: https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_norm16.txt + /// OpenGLES: [GL_EXT_texture_norm16][] extension is required + TEX_FORMAT_RGBA16_SNORM, + + /// Four-component 64-bit signed-integer format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16B16A16_SINT. OpenGL counterpart: GL_RGBA16I. + TEX_FORMAT_RGBA16_SINT, + + /// Two-component 64-bit typeless format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32_TYPELESS. OpenGL does not have direct counterpart, GL_RG32F is used. + TEX_FORMAT_RG32_TYPELESS, + + /// Two-component 64-bit floating-point format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32_FLOAT. OpenGL counterpart: GL_RG32F. + TEX_FORMAT_RG32_FLOAT, + + /// Two-component 64-bit unsigned-integer format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32_UINT. OpenGL counterpart: GL_RG32UI. + TEX_FORMAT_RG32_UINT, + + /// Two-component 64-bit signed-integer format with 32-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R32G32_SINT. OpenGL counterpart: GL_RG32I. + TEX_FORMAT_RG32_SINT, + + /// Two-component 64-bit typeless format with 32-bits for R channel and 8 bits for G channel. \n + /// D3D counterpart: DXGI_FORMAT_R32G8X24_TYPELESS. OpenGL does not have direct counterpart, GL_DEPTH32F_STENCIL8 is used. + TEX_FORMAT_R32G8X24_TYPELESS, + + /// Two-component 64-bit format with 32-bit floating-point depth channel and 8-bit stencil channel. \n + /// D3D counterpart: DXGI_FORMAT_D32_FLOAT_S8X24_UINT. OpenGL counterpart: GL_DEPTH32F_STENCIL8. + TEX_FORMAT_D32_FLOAT_S8X24_UINT, + + /// Two-component 64-bit format with 32-bit floating-point R channel and 8+24-bits of typeless data. \n + /// D3D counterpart: DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS. OpenGL does not have direct counterpart, GL_DEPTH32F_STENCIL8 is used. + TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS, + + /// Two-component 64-bit format with 32-bit typeless data and 8-bit G channel. \n + /// D3D counterpart: DXGI_FORMAT_X32_TYPELESS_G8X24_UINT + /// \warning This format is currently not implemented in OpenGL version + TEX_FORMAT_X32_TYPELESS_G8X24_UINT, + + /// Four-component 32-bit typeless format with 10 bits for RGB and 2 bits for alpha channel. \n + /// D3D counterpart: DXGI_FORMAT_R10G10B10A2_TYPELESS. OpenGL does not have direct counterpart, GL_RGB10_A2 is used. + TEX_FORMAT_RGB10A2_TYPELESS, + + /// Four-component 32-bit unsigned-normalized-integer format with 10 bits for each color and 2 bits for alpha channel. \n + /// D3D counterpart: DXGI_FORMAT_R10G10B10A2_UNORM. OpenGL counterpart: GL_RGB10_A2. + TEX_FORMAT_RGB10A2_UNORM, + + /// Four-component 32-bit unsigned-integer format with 10 bits for each color and 2 bits for alpha channel. \n + /// D3D counterpart: DXGI_FORMAT_R10G10B10A2_UINT. OpenGL counterpart: GL_RGB10_A2UI. + TEX_FORMAT_RGB10A2_UINT, + + /// Three-component 32-bit format encoding three partial precision channels using 11 bits for red and green and 10 bits for blue channel. \n + /// D3D counterpart: DXGI_FORMAT_R11G11B10_FLOAT. OpenGL counterpart: GL_R11F_G11F_B10F. + TEX_FORMAT_R11G11B10_FLOAT, + + /// Four-component 32-bit typeless format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8B8A8_TYPELESS. OpenGL does not have direct counterpart, GL_RGBA8 is used. + TEX_FORMAT_RGBA8_TYPELESS, + + /// Four-component 32-bit unsigned-normalized-integer format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8B8A8_UNORM. OpenGL counterpart: GL_RGBA8. + TEX_FORMAT_RGBA8_UNORM, + + /// Four-component 32-bit unsigned-normalized-integer sRGB format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8B8A8_UNORM_SRGB. OpenGL counterpart: GL_SRGB8_ALPHA8. + TEX_FORMAT_RGBA8_UNORM_SRGB, + + /// Four-component 32-bit unsigned-integer format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8B8A8_UINT. OpenGL counterpart: GL_RGBA8UI. + TEX_FORMAT_RGBA8_UINT, + + /// Four-component 32-bit signed-normalized-integer format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8B8A8_SNORM. OpenGL counterpart: GL_RGBA8_SNORM. + TEX_FORMAT_RGBA8_SNORM, + + /// Four-component 32-bit signed-integer format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8B8A8_SINT. OpenGL counterpart: GL_RGBA8I. + TEX_FORMAT_RGBA8_SINT, + + /// Two-component 32-bit typeless format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16_TYPELESS. OpenGL does not have direct counterpart, GL_RG16F is used. + TEX_FORMAT_RG16_TYPELESS, + + /// Two-component 32-bit half-precision floating-point format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16_FLOAT. OpenGL counterpart: GL_RG16F. + TEX_FORMAT_RG16_FLOAT, + + /// Two-component 32-bit unsigned-normalized-integer format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16_UNORM. OpenGL counterpart: GL_RG16. \n + /// [GL_EXT_texture_norm16]: https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_norm16.txt + /// OpenGLES: [GL_EXT_texture_norm16][] extension is required + TEX_FORMAT_RG16_UNORM, + + /// Two-component 32-bit unsigned-integer format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16_UINT. OpenGL counterpart: GL_RG16UI. + TEX_FORMAT_RG16_UINT, + + /// Two-component 32-bit signed-normalized-integer format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16_SNORM. OpenGL counterpart: GL_RG16_SNORM. \n + /// [GL_EXT_texture_norm16]: https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_norm16.txt + /// OpenGLES: [GL_EXT_texture_norm16][] extension is required + TEX_FORMAT_RG16_SNORM, + + /// Two-component 32-bit signed-integer format with 16-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R16G16_SINT. OpenGL counterpart: GL_RG16I. + TEX_FORMAT_RG16_SINT, + + /// Single-component 32-bit typeless format. \n + /// D3D counterpart: DXGI_FORMAT_R32_TYPELESS. OpenGL does not have direct counterpart, GL_R32F is used. + TEX_FORMAT_R32_TYPELESS, + + /// Single-component 32-bit floating-point depth format. \n + /// D3D counterpart: DXGI_FORMAT_D32_FLOAT. OpenGL counterpart: GL_DEPTH_COMPONENT32F. + TEX_FORMAT_D32_FLOAT, + + /// Single-component 32-bit floating-point format. \n + /// D3D counterpart: DXGI_FORMAT_R32_FLOAT. OpenGL counterpart: GL_R32F. + TEX_FORMAT_R32_FLOAT, + + /// Single-component 32-bit unsigned-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R32_UINT. OpenGL counterpart: GL_R32UI. + TEX_FORMAT_R32_UINT, + + /// Single-component 32-bit signed-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R32_SINT. OpenGL counterpart: GL_R32I. + TEX_FORMAT_R32_SINT, + + /// Two-component 32-bit typeless format with 24 bits for R and 8 bits for G channel. \n + /// D3D counterpart: DXGI_FORMAT_R24G8_TYPELESS. OpenGL does not have direct counterpart, GL_DEPTH24_STENCIL8 is used. + TEX_FORMAT_R24G8_TYPELESS, + + /// Two-component 32-bit format with 24 bits for unsigned-normalized-integer depth and 8 bits for stencil. \n + /// D3D counterpart: DXGI_FORMAT_D24_UNORM_S8_UINT. OpenGL counterpart: GL_DEPTH24_STENCIL8. + TEX_FORMAT_D24_UNORM_S8_UINT, + + /// Two-component 32-bit format with 24 bits for unsigned-normalized-integer data and 8 bits of unreferenced data. \n + /// D3D counterpart: DXGI_FORMAT_R24_UNORM_X8_TYPELESS. OpenGL does not have direct counterpart, GL_DEPTH24_STENCIL8 is used. + TEX_FORMAT_R24_UNORM_X8_TYPELESS, + + /// Two-component 32-bit format with 24 bits of unreferenced data and 8 bits of unsigned-integer data. \n + /// D3D counterpart: DXGI_FORMAT_X24_TYPELESS_G8_UINT + /// \warning This format is currently not implemented in OpenGL version + TEX_FORMAT_X24_TYPELESS_G8_UINT, + + /// Two-component 16-bit typeless format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8_TYPELESS. OpenGL does not have direct counterpart, GL_RG8 is used. + TEX_FORMAT_RG8_TYPELESS, + + /// Two-component 16-bit unsigned-normalized-integer format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8_UNORM. OpenGL counterpart: GL_RG8. + TEX_FORMAT_RG8_UNORM, + + /// Two-component 16-bit unsigned-integer format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8_UINT. OpenGL counterpart: GL_RG8UI. + TEX_FORMAT_RG8_UINT, + + /// Two-component 16-bit signed-normalized-integer format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8_SNORM. OpenGL counterpart: GL_RG8_SNORM. + TEX_FORMAT_RG8_SNORM, + + /// Two-component 16-bit signed-integer format with 8-bit channels. \n + /// D3D counterpart: DXGI_FORMAT_R8G8_SINT. OpenGL counterpart: GL_RG8I. + TEX_FORMAT_RG8_SINT, + + /// Single-component 16-bit typeless format. \n + /// D3D counterpart: DXGI_FORMAT_R16_TYPELESS. OpenGL does not have direct counterpart, GL_R16F is used. + TEX_FORMAT_R16_TYPELESS, + + /// Single-component 16-bit half-precisoin floating-point format. \n + /// D3D counterpart: DXGI_FORMAT_R16_FLOAT. OpenGL counterpart: GL_R16F. + TEX_FORMAT_R16_FLOAT, + + /// Single-component 16-bit unsigned-normalized-integer depth format. \n + /// D3D counterpart: DXGI_FORMAT_D16_UNORM. OpenGL counterpart: GL_DEPTH_COMPONENT16. + TEX_FORMAT_D16_UNORM, + + /// Single-component 16-bit unsigned-normalized-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R16_UNORM. OpenGL counterpart: GL_R16. + /// [GL_EXT_texture_norm16]: https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_norm16.txt + /// OpenGLES: [GL_EXT_texture_norm16][] extension is required + TEX_FORMAT_R16_UNORM, + + /// Single-component 16-bit unsigned-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R16_UINT. OpenGL counterpart: GL_R16UI. + TEX_FORMAT_R16_UINT, + + /// Single-component 16-bit signed-normalized-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R16_SNORM. OpenGL counterpart: GL_R16_SNORM. \n + /// [GL_EXT_texture_norm16]: https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_norm16.txt + /// OpenGLES: [GL_EXT_texture_norm16][] extension is required + TEX_FORMAT_R16_SNORM, + + /// Single-component 16-bit signed-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R16_SINT. OpenGL counterpart: GL_R16I. + TEX_FORMAT_R16_SINT, + + /// Single-component 8-bit typeless format. \n + /// D3D counterpart: DXGI_FORMAT_R8_TYPELESS. OpenGL does not have direct counterpart, GL_R8 is used. + TEX_FORMAT_R8_TYPELESS, + + /// Single-component 8-bit unsigned-normalized-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R8_UNORM. OpenGL counterpart: GL_R8. + TEX_FORMAT_R8_UNORM, + + /// Single-component 8-bit unsigned-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R8_UINT. OpenGL counterpart: GL_R8UI. + TEX_FORMAT_R8_UINT, + + /// Single-component 8-bit signed-normalized-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R8_SNORM. OpenGL counterpart: GL_R8_SNORM. + TEX_FORMAT_R8_SNORM, + + /// Single-component 8-bit signed-integer format. \n + /// D3D counterpart: DXGI_FORMAT_R8_SINT. OpenGL counterpart: GL_R8I. + TEX_FORMAT_R8_SINT, + + /// Single-component 8-bit unsigned-normalized-integer format for alpha only. \n + /// D3D counterpart: DXGI_FORMAT_A8_UNORM + /// \warning This format is not availanle in OpenGL + TEX_FORMAT_A8_UNORM, + + /// Single-component 1-bit format. \n + /// D3D counterpart: DXGI_FORMAT_R1_UNORM + /// \warning This format is not availanle in OpenGL + TEX_FORMAT_R1_UNORM, + + /// Three partial-precision floating pointer numbers sharing single exponent encoded into a 32-bit value. \n + /// D3D counterpart: DXGI_FORMAT_R9G9B9E5_SHAREDEXP. OpenGL counterpart: GL_RGB9_E5. + TEX_FORMAT_RGB9E5_SHAREDEXP, + + /// Four-component unsigned-normalized integer format analogous to UYVY encoding. \n + /// D3D counterpart: DXGI_FORMAT_R8G8_B8G8_UNORM + /// \warning This format is not availanle in OpenGL + TEX_FORMAT_RG8_B8G8_UNORM, + + /// Four-component unsigned-normalized integer format analogous to YUY2 encoding. \n + /// D3D counterpart: DXGI_FORMAT_G8R8_G8B8_UNORM + /// \warning This format is not availanle in OpenGL + TEX_FORMAT_G8R8_G8B8_UNORM, + + /// Four-component typeless block-compression format with 1:8 compression ratio.\n + /// D3D counterpart: DXGI_FORMAT_BC1_TYPELESS. OpenGL does not have direct counterpart, GL_COMPRESSED_RGB_S3TC_DXT1_EXT is used. \n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC1">BC1 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT1_Format">DXT1 on OpenGL.org </a> + TEX_FORMAT_BC1_TYPELESS, + + /// Four-component unsigned-normalized-integer block-compression format with 5 bits for R, 6 bits for G, 5 bits for B, and 0 or 1 bit for A channel. + /// The pixel data is encoded using 8 bytes per 4x4 block (4 bits per pixel) providing 1:8 compression ratio against RGBA8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC1_UNORM. OpenGL counterpart: GL_COMPRESSED_RGB_S3TC_DXT1_EXT.\n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC1">BC1 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT1_Format">DXT1 on OpenGL.org </a> + TEX_FORMAT_BC1_UNORM, + + /// Four-component unsigned-normalized-integer block-compression sRGB format with 5 bits for R, 6 bits for G, 5 bits for B, and 0 or 1 bit for A channel. \n + /// The pixel data is encoded using 8 bytes per 4x4 block (4 bits per pixel) providing 1:8 compression ratio against RGBA8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC1_UNORM_SRGB. OpenGL counterpart: GL_COMPRESSED_SRGB_S3TC_DXT1_EXT.\n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC1">BC1 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT1_Format">DXT1 on OpenGL.org </a> + TEX_FORMAT_BC1_UNORM_SRGB, + + /// Four component typeless block-compression format with 1:4 compression ratio.\n + /// D3D counterpart: DXGI_FORMAT_BC2_TYPELESS. OpenGL does not have direct counterpart, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT is used. \n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC2">BC2 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT3_Format">DXT3 on OpenGL.org </a> + TEX_FORMAT_BC2_TYPELESS, + + /// Four-component unsigned-normalized-integer block-compression format with 5 bits for R, 6 bits for G, 5 bits for B, and 4 bits for low-coherent separate A channel. + /// The pixel data is encoded using 16 bytes per 4x4 block (8 bits per pixel) providing 1:4 compression ratio against RGBA8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC2_UNORM. OpenGL counterpart: GL_COMPRESSED_RGBA_S3TC_DXT3_EXT. \n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC2">BC2 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT3_Format">DXT3 on OpenGL.org </a> + TEX_FORMAT_BC2_UNORM, + + /// Four-component signed-normalized-integer block-compression sRGB format with 5 bits for R, 6 bits for G, 5 bits for B, and 4 bits for low-coherent separate A channel. + /// The pixel data is encoded using 16 bytes per 4x4 block (8 bits per pixel) providing 1:4 compression ratio against RGBA8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC2_UNORM_SRGB. OpenGL counterpart: GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT. \n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC2">BC2 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT3_Format">DXT3 on OpenGL.org </a> + TEX_FORMAT_BC2_UNORM_SRGB, + + /// Four-component typeless block-compression format with 1:4 compression ratio.\n + /// D3D counterpart: DXGI_FORMAT_BC3_TYPELESS. OpenGL does not have direct counterpart, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT is used. \n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC3">BC3 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT5_Format">DXT5 on OpenGL.org </a> + TEX_FORMAT_BC3_TYPELESS, + + /// Four-component unsigned-normalized-integer block-compression format with 5 bits for R, 6 bits for G, 5 bits for B, and 8 bits for highly-coherent A channel. + /// The pixel data is encoded using 16 bytes per 4x4 block (8 bits per pixel) providing 1:4 compression ratio against RGBA8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC3_UNORM. OpenGL counterpart: GL_COMPRESSED_RGBA_S3TC_DXT5_EXT. \n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC3">BC3 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT5_Format">DXT5 on OpenGL.org </a> + TEX_FORMAT_BC3_UNORM, + + /// Four-component unsigned-normalized-integer block-compression sRGB format with 5 bits for R, 6 bits for G, 5 bits for B, and 8 bits for highly-coherent A channel. + /// The pixel data is encoded using 16 bytes per 4x4 block (8 bits per pixel) providing 1:4 compression ratio against RGBA8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC3_UNORM_SRGB. OpenGL counterpart: GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT. \n + /// [GL_EXT_texture_compression_s3tc]: https://www.khronos.org/registry/gles/extensions/EXT/texture_compression_s3tc.txt + /// OpenGL & OpenGLES: [GL_EXT_texture_compression_s3tc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC3">BC3 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/S3_Texture_Compression#DXT5_Format">DXT5 on OpenGL.org </a> + TEX_FORMAT_BC3_UNORM_SRGB, + + /// One-component typeless block-compression format with 1:2 compression ratio. \n + /// D3D counterpart: DXGI_FORMAT_BC4_TYPELESS. OpenGL does not have direct counterpart, GL_COMPRESSED_RED_RGTC1 is used. \n + /// [GL_ARB_texture_compression_rgtc]: https://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt + /// OpenGL & OpenGLES: [GL_ARB_texture_compression_rgtc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC4">BC4 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/Image_Format#Compressed_formats">Compressed formats on OpenGL.org </a> + TEX_FORMAT_BC4_TYPELESS, + + /// One-component unsigned-normalized-integer block-compression format with 8 bits for R channel. + /// The pixel data is encoded using 8 bytes per 4x4 block (4 bits per pixel) providing 1:2 compression ratio against R8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC4_UNORM. OpenGL counterpart: GL_COMPRESSED_RED_RGTC1. \n + /// [GL_ARB_texture_compression_rgtc]: https://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt + /// OpenGL & OpenGLES: [GL_ARB_texture_compression_rgtc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC4">BC4 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/Image_Format#Compressed_formats">Compressed formats on OpenGL.org </a> + TEX_FORMAT_BC4_UNORM, + + /// One-component signed-normalized-integer block-compression format with 8 bits for R channel. + /// The pixel data is encoded using 8 bytes per 4x4 block (4 bits per pixel) providing 1:2 compression ratio against R8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC4_SNORM. OpenGL counterpart: GL_COMPRESSED_SIGNED_RED_RGTC1. \n + /// [GL_ARB_texture_compression_rgtc]: https://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt + /// OpenGL & OpenGLES: [GL_ARB_texture_compression_rgtc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC4">BC4 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/Image_Format#Compressed_formats">Compressed formats on OpenGL.org </a> + TEX_FORMAT_BC4_SNORM, + + /// Two-component typeless block-compression format with 1:2 compression ratio. \n + /// D3D counterpart: DXGI_FORMAT_BC5_TYPELESS. OpenGL does not have direct counterpart, GL_COMPRESSED_RG_RGTC2 is used. \n + /// [GL_ARB_texture_compression_rgtc]: https://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt + /// OpenGL & OpenGLES: [GL_ARB_texture_compression_rgtc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC5">BC5 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/Image_Format#Compressed_formats">Compressed formats on OpenGL.org </a> + TEX_FORMAT_BC5_TYPELESS, + + /// Two-component unsigned-normalized-integer block-compression format with 8 bits for R and 8 bits for G channel. + /// The pixel data is encoded using 16 bytes per 4x4 block (8 bits per pixel) providing 1:2 compression ratio against RG8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC5_UNORM. OpenGL counterpart: GL_COMPRESSED_RG_RGTC2. \n + /// [GL_ARB_texture_compression_rgtc]: https://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt + /// OpenGL & OpenGLES: [GL_ARB_texture_compression_rgtc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC5">BC5 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/Image_Format#Compressed_formats">Compressed formats on OpenGL.org </a> + TEX_FORMAT_BC5_UNORM, + + /// Two-component signed-normalized-integer block-compression format with 8 bits for R and 8 bits for G channel. + /// The pixel data is encoded using 16 bytes per 4x4 block (8 bits per pixel) providing 1:2 compression ratio against RG8 format. \n + /// D3D counterpart: DXGI_FORMAT_BC5_SNORM. OpenGL counterpart: GL_COMPRESSED_SIGNED_RG_RGTC2. \n + /// [GL_ARB_texture_compression_rgtc]: https://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt + /// OpenGL & OpenGLES: [GL_ARB_texture_compression_rgtc][] extension is required + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC5">BC5 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/Image_Format#Compressed_formats">Compressed formats on OpenGL.org </a> + TEX_FORMAT_BC5_SNORM, + + /// Three-component 16-bit unsigned-normalized-integer format with 5 bits for blue, 6 bits for green, and 5 bits for red channel. \n + /// D3D counterpart: DXGI_FORMAT_B5G6R5_UNORM + /// \warning This format is not available until D3D11.1 and Windows 8. It is also not available in OpenGL + TEX_FORMAT_B5G6R5_UNORM, + + /// Four-component 16-bit unsigned-normalized-integer format with 5 bits for each color channel and 1-bit alpha. \n + /// D3D counterpart: DXGI_FORMAT_B5G5R5A1_UNORM + /// \warning This format is not available until D3D11.1 and Windows 8. It is also not available in OpenGL + TEX_FORMAT_B5G5R5A1_UNORM, + + /// Four-component 32-bit unsigned-normalized-integer format with 8 bits for each channel. \n + /// D3D counterpart: DXGI_FORMAT_B8G8R8A8_UNORM. + /// \warning This format is not available in OpenGL + TEX_FORMAT_BGRA8_UNORM, + + /// Four-component 32-bit unsigned-normalized-integer format with 8 bits for each color channel and 8 bits unused. \n + /// D3D counterpart: DXGI_FORMAT_B8G8R8X8_UNORM. + /// \warning This format is not available in OpenGL + TEX_FORMAT_BGRX8_UNORM, + + /// Four-component 32-bit 2.8-biased fixed-point format with 10 bits for each color channel and 2-bit alpha. \n + /// D3D counterpart: DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM. + /// \warning This format is not available in OpenGL + TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, + + /// Four-component 32-bit typeless format with 8 bits for each channel. \n + /// D3D counterpart: DXGI_FORMAT_B8G8R8A8_TYPELESS. + /// \warning This format is not available in OpenGL + TEX_FORMAT_BGRA8_TYPELESS, + + /// Four-component 32-bit unsigned-normalized sRGB format with 8 bits for each channel. \n + /// D3D counterpart: DXGI_FORMAT_B8G8R8A8_UNORM_SRGB. + /// \warning This format is not available in OpenGL. + TEX_FORMAT_BGRA8_UNORM_SRGB, + + /// Four-component 32-bit typeless format that with 8 bits for each color channel, and 8 bits are unused. \n + /// D3D counterpart: DXGI_FORMAT_B8G8R8X8_TYPELESS. + /// \warning This format is not available in OpenGL. + TEX_FORMAT_BGRX8_TYPELESS, + + /// Four-component 32-bit unsigned-normalized sRGB format with 8 bits for each color channel, and 8 bits are unused. \n + /// D3D counterpart: DXGI_FORMAT_B8G8R8X8_UNORM_SRGB. + /// \warning This format is not available in OpenGL. + TEX_FORMAT_BGRX8_UNORM_SRGB, + + /// Three-component typeless block-compression format. \n + /// D3D counterpart: DXGI_FORMAT_BC6H_TYPELESS. OpenGL does not have direct counterpart, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT is used. \n + /// [GL_ARB_texture_compression_bptc]: https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/specs/ARB/texture_compression_bptc.txt + /// OpenGL: [GL_ARB_texture_compression_bptc][] extension is required. Not supported in at least OpenGLES3.1 + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/hh308952(v=vs.85).aspx">BC6H on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/BPTC_Texture_Compression">BPTC Texture Compression on OpenGL.org </a> + TEX_FORMAT_BC6H_TYPELESS, + + /// Three-component unsigned half-precision floating-point format with 16 bits for each channel. \n + /// D3D counterpart: DXGI_FORMAT_BC6H_UF16. OpenGL counterpart: GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT. \n + /// [GL_ARB_texture_compression_bptc]: https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/specs/ARB/texture_compression_bptc.txt + /// OpenGL: [GL_ARB_texture_compression_bptc][] extension is required. Not supported in at least OpenGLES3.1 + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/hh308952(v=vs.85).aspx">BC6H on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/BPTC_Texture_Compression">BPTC Texture Compression on OpenGL.org </a> + TEX_FORMAT_BC6H_UF16, + + /// Three-channel signed half-precision floating-point format with 16 bits per each channel. \n + /// D3D counterpart: DXGI_FORMAT_BC6H_SF16. OpenGL counterpart: GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT. \n + /// [GL_ARB_texture_compression_bptc]: https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/specs/ARB/texture_compression_bptc.txt + /// OpenGL: [GL_ARB_texture_compression_bptc][] extension is required. Not supported in at least OpenGLES3.1 + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/hh308952(v=vs.85).aspx">BC6H on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/BPTC_Texture_Compression">BPTC Texture Compression on OpenGL.org </a> + TEX_FORMAT_BC6H_SF16, + + /// Three-component typeless block-compression format. \n + /// D3D counterpart: DXGI_FORMAT_BC7_TYPELESS. OpenGL does not have direct counterpart, GL_COMPRESSED_RGBA_BPTC_UNORM is used. \n + /// [GL_ARB_texture_compression_bptc]: https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/specs/ARB/texture_compression_bptc.txt + /// OpenGL: [GL_ARB_texture_compression_bptc][] extension is required. Not supported in at least OpenGLES3.1 + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/hh308953(v=vs.85).aspx">BC7 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/BPTC_Texture_Compression">BPTC Texture Compression on OpenGL.org </a> + TEX_FORMAT_BC7_TYPELESS, + + /// Three-component block-compression unsigned-normalized-integer format with 4 to 7 bits per color channel and 0 to 8 bits of alpha. \n + /// D3D counterpart: DXGI_FORMAT_BC7_UNORM. OpenGL counterpart: GL_COMPRESSED_RGBA_BPTC_UNORM. \n + /// [GL_ARB_texture_compression_bptc]: https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/specs/ARB/texture_compression_bptc.txt + /// OpenGL: [GL_ARB_texture_compression_bptc][] extension is required. Not supported in at least OpenGLES3.1 + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/hh308953(v=vs.85).aspx">BC7 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/BPTC_Texture_Compression">BPTC Texture Compression on OpenGL.org </a> + TEX_FORMAT_BC7_UNORM, + + /// Three-component block-compression unsigned-normalized-integer sRGB format with 4 to 7 bits per color channel and 0 to 8 bits of alpha. \n + /// D3D counterpart: DXGI_FORMAT_BC7_UNORM_SRGB. OpenGL counterpart: GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM. \n + /// [GL_ARB_texture_compression_bptc]: https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/specs/ARB/texture_compression_bptc.txt + /// OpenGL: [GL_ARB_texture_compression_bptc][] extension is required. Not supported in at least OpenGLES3.1 + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/hh308953(v=vs.85).aspx">BC7 on MSDN </a>, + /// <a href = "https://www.opengl.org/wiki/BPTC_Texture_Compression">BPTC Texture Compression on OpenGL.org </a> + TEX_FORMAT_BC7_UNORM_SRGB, + + /// Helper member containing the total number of texture formats in the enumeration + TEX_FORMAT_NUM_FORMATS + }; + + /// Filter type + + /// This enumeration defines filter type. It is used by SamplerDesc structure to define min, mag and mip filters. + /// \note On D3D11, comparison filters only work with textures that have the following formats: + /// R32_FLOAT_X8X24_TYPELESS, R32_FLOAT, R24_UNORM_X8_TYPELESS, R16_UNORM. + enum FILTER_TYPE : Int32 + { + FILTER_TYPE_UNKNOWN = 0, ///< Unknown filter type + FILTER_TYPE_POINT, ///< Point filtering + FILTER_TYPE_LINEAR, ///< Linear filtering + FILTER_TYPE_ANISOTROPIC, ///< Anisotropic filtering + FILTER_TYPE_COMPARISON_POINT, ///< Comparison-point filtering + FILTER_TYPE_COMPARISON_LINEAR, ///< Comparison-linear filtering + FILTER_TYPE_COMPARISON_ANISOTROPIC, ///< Comparison-anisotropic filtering + FILTER_TYPE_NUM_FILTERS ///< Helper value that stores the total number of filter types in the enumeration + }; + + /// Texture address mode + + /// [D3D11_TEXTURE_ADDRESS_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476256(v=vs.85).aspx + /// Defines a technique for resolving texture coordinates that are outside of + /// the boundaries of a texture. The enumeration generally mirrows [D3D11_TEXTURE_ADDRESS_MODE][] enumeration. + /// It is used by SamplerDesc structure to define the address mode for U,V and W texture coordinates. + enum TEXTURE_ADDRESS_MODE : Int32 + { + /// Unknown mode + TEXTURE_ADDRESS_UNKNOWN = 0, + + /// Tile the texture at every integer junction. \n + /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_WRAP. OpenGL counterpart: GL_REPEAT + TEXTURE_ADDRESS_WRAP = 1, + + /// Flip the texture at every integer junction. \n + /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_MIRROR. OpenGL counterpart: GL_MIRRORED_REPEAT + TEXTURE_ADDRESS_MIRROR = 2, + + /// Texture coordinates outside the range [0.0, 1.0] are set to the + /// texture color at 0.0 or 1.0, respectively. \n + /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_CLAMP. OpenGL counterpart: GL_CLAMP_TO_EDGE + TEXTURE_ADDRESS_CLAMP = 3, + + /// Texture coordinates outside the range [0.0, 1.0] are set to the border color specified + /// specified in SamplerDesc structure. \n + /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_BORDER. OpenGL counterpart: GL_CLAMP_TO_BORDER + TEXTURE_ADDRESS_BORDER = 4, + + /// Similar to TEXTURE_ADDRESS_MIRROR and TEXTURE_ADDRESS_CLAMP. Takes the absolute + /// value of the texture coordinate (thus, mirroring around 0), and then clamps to + /// the maximum value. \n + /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_MIRROR_ONCE. OpenGL counterpart: GL_MIRROR_CLAMP_TO_EDGE + /// \note GL_MIRROR_CLAMP_TO_EDGE is only available in OpenGL4.4+, and is not available until at least OpenGLES3.1 + TEXTURE_ADDRESS_MIRROR_ONCE = 5, + + /// Helper value that stores the total number of texture address modes in the enumeration + TEXTURE_ADDRESS_NUM_MODES + }; + + /// Comparison function + + /// [D3D11_COMPARISON_FUNC]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476101(v=vs.85).aspx + /// This enumeartion defines a comparison function. It generally mirrows [D3D11_COMPARISON_FUNC] enum and is used by + /// - SamplerDesc to define a comparison function if one of the comparison mode filters is used + /// - StencilOpDesc to define a stencil function + /// - DepthStencilStateDesc to define a depth function + enum COMPARISON_FUNCTION : Int32 + { + /// Unknown comparison function + COMPARISON_FUNC_UNKNOW = 0, + + /// Comparison never passes. \n + /// D3D11 counterpart: D3D11_COMPARISON_NEVER. OpenGL counterpart: GL_NEVER. + COMPARISON_FUNC_NEVER, + + /// Comparison passes if the source data is less than the destination data.\n + /// D3D11 counterpart: D3D11_COMPARISON_LESS. OpenGL counterpart: GL_LESS. + COMPARISON_FUNC_LESS, + + /// Comparison passes if the source data is equal to the destination data.\n + /// D3D11 counterpart: 3D11_COMPARISON_EQUAL. OpenGL counterpart: GL_EQUAL. + COMPARISON_FUNC_EQUAL, + + /// Comparison passes if the source data is less than or equal to the destination data.\n + /// D3D11 counterpart: D3D11_COMPARISON_LESS_EQUAL. OpenGL counterpart: GL_LEQUAL. + COMPARISON_FUNC_LESS_EQUAL, + + /// Comparison passes if the source data is greater than the destination data.\n + /// D3D11 counterpart: 3D11_COMPARISON_GREATER. OpenGL counterpart: GL_GREATER. + COMPARISON_FUNC_GREATER, + + /// Comparison passes if the source data is not equal to the destination data.\n + /// D3D11 counterpart: D3D11_COMPARISON_NOT_EQUAL. OpenGL counterpart: GL_NOTEQUAL. + COMPARISON_FUNC_NOT_EQUAL, + + /// Comparison passes if the source data is greater than or equal to the destination data.\n + /// D3D11 counterpart: D3D11_COMPARISON_GREATER_EQUAL. OpenGL counterpart: GL_GEQUAL. + COMPARISON_FUNC_GREATER_EQUAL, + + /// Comparison always passes. \n + /// D3D11 counterpart: D3D11_COMPARISON_ALWAYS. OpenGL counterpart: GL_ALWAYS. + COMPARISON_FUNC_ALWAYS, + + /// Helper value that stores the total number of comparison functions in the enumeration + COMPARISON_FUNC_NUM_FUNCTIONS + }; + + /// Miscellaneous texture flags + + /// The enumeration is used by TextureDesc to describe misc texture flags + enum MISC_TEXTURE_FLAG + { + /// Allow automatic mipmap generation with ITextureView::GenerateMips() + + /// \note A texture must be created with BIND_RENDER_TARGET bind flag + MISC_TEXTURE_FLAG_GENERATE_MIPS = 0x01 + }; + + /// Describes common device object attributes + struct DeviceObjectAttribs + { + /// Object name + const Char* Name; + + /// Constructor intializes the structure members with default values + DeviceObjectAttribs() : + Name(nullptr) + {} + }; + + /// Swap chain description + struct SwapChainDesc + { + /// The swap chain width. Default value is 0 + Uint32 Width; + + /// The swap chain height. Default value is 0 + Uint32 Height; + + /// Back buffer format. Default value is TEX_FORMAT_RGBA8_UNORM_SRGB + TEXTURE_FORMAT ColorBufferFormat; + + /// Depth buffer format. Default value is TEX_FORMAT_D32_FLOAT + TEXTURE_FORMAT DepthBufferFormat; + + /// Sample count. Default value is 1 + Uint32 SamplesCount; + + /// Constructor intializes the structure members with default values + SwapChainDesc() : + Width(0), + Height(0), + ColorBufferFormat( TEX_FORMAT_RGBA8_UNORM_SRGB ), + DepthBufferFormat( TEX_FORMAT_D32_FLOAT ), + SamplesCount( 1 ) + {} + }; + + /// Engine creation attibutes + struct EngineCreationAttribs + { + const Char* strShaderCachePath; + + EngineCreationAttribs() : + strShaderCachePath(nullptr) + {} + }; + + /// Box + struct Box + { + Uint32 MinX; ///< Minimal X coordinate. Default value is 0 + Uint32 MaxX; ///< Maximal X coordinate. Default value is 0 + Uint32 MinY; ///< Minimal Y coordinate. Default value is 0 + Uint32 MaxY; ///< Maximal Y coordinate. Default value is 0 + Uint32 MinZ; ///< Minimal Z coordinate. Default value is 0 + Uint32 MaxZ; ///< Maximal Z coordinate. Default value is 1 + + /// Constructor intializes the structure + Box(Uint32 _MinX = 0, Uint32 _MaxX = 0, + Uint32 _MinY = 0, Uint32 _MaxY = 0, + Uint32 _MinZ = 0, Uint32 _MaxZ = 1) : + MinX(_MinX), MaxX(_MaxX), + MinY(_MinY), MaxY(_MaxY), + MinZ(_MinZ), MaxZ(_MaxZ) + {} + }; + + + /// Describes texture format component type + enum COMPONENT_TYPE : Int32 + { + /// Undefined component type + COMPONENT_TYPE_UNDEFINED, + + /// Floating point component type + COMPONENT_TYPE_FLOAT, + + /// Signed-normalized-integer component type + COMPONENT_TYPE_SNORM, + + /// Unsigned-normalized-integer component type + COMPONENT_TYPE_UNORM, + + /// Unsigned-normalized-integer sRGB component type + COMPONENT_TYPE_UNORM_SRGB, + + /// Signed-integer component type + COMPONENT_TYPE_SINT, + + /// Unsigned-integer component type + COMPONENT_TYPE_UINT, + + /// Depth component type + COMPONENT_TYPE_DEPTH, + + /// Depth-stencil component type + COMPONENT_TYPE_DEPTH_STENCIL, + + /// Compound component type (example texture formats: TEX_FORMAT_R11G11B10_FLOAT or TEX_FORMAT_RGB9E5_SHAREDEXP) + COMPONENT_TYPE_COMPOUND, + + /// Compressed component type + COMPONENT_TYPE_COMPRESSED, + }; + + /// Describes invariant texture format attributes. These attributes are + /// intrinsic to the texture format itself and do not depend on the + /// format support. + struct TextureFormatAttribs + { + /// Texture format, see Diligent::TEXTURE_FORMAT for a list of supported texture formats + TEXTURE_FORMAT Format; + + /// Literal texture format name (for instance, for TEX_FORMAT_RGBA8_UNORM format, this + /// will be "TEX_FORMAT_RGBA8_UNORM") + const Char *Name; + + /// Size of one component in bytes (for instance, for TEX_FORMAT_RGBA8_UNORM format, this will be 1) + /// For compressed formats, this is the block size in bytes (for TEX_FORMAT_BC1_UNORM format, this will be 8) + Uint32 ComponentSize; + + /// Number of components + Uint32 NumComponents; + + /// Component type, see Diligent::COMPONENT_TYPE for details. + COMPONENT_TYPE ComponentType; + + /// Initializes the structure + explicit TextureFormatAttribs( TEXTURE_FORMAT _Format = TEX_FORMAT_UNKNOWN, + const Char *_Name = "TEX_FORMAT_UNKNOWN", + Uint32 _ComponentSize = 0, + Uint32 _NumComponents = 0, + COMPONENT_TYPE _ComponentType = COMPONENT_TYPE_UNDEFINED ) : + Format(_Format), + Name(_Name), + ComponentSize(_ComponentSize), + NumComponents(_NumComponents), + ComponentType(_ComponentType) + {} + }; + + /// Basic texture format description + + /// This structure is returned by IRenderDevice::GetTextureFormatInfo() + struct TextureFormatInfo : public TextureFormatAttribs + { + /// Indicates if the format is supported by the device + bool Supported; + + /// Initializes the structure with default values + explicit TextureFormatInfo() : + Supported(false) + {} + }; + + /// Extended texture format description + + /// This structure is returned by IRenderDevice::GetTextureFormatInfoExt() + struct TextureFormatInfoExt : TextureFormatInfo + { + /// Indicates if the format can be filtered + bool Filterable; + + /// Indicates if the format can be used as a render target format + bool ColorRenderable; + + /// Indicates if the format can be used as a depth format + bool DepthRenderable; + + /// Indicates if the format can be used to create a 1D texture + bool Tex1DFmt; + + /// Indicates if the format can be used to create a 2D texture + bool Tex2DFmt; + + /// Indicates if the format can be used to create a 3D texture + bool Tex3DFmt; + + /// Indicates if the format can be used to create a cube texture + bool TexCubeFmt; + + /// Indicates if the format can be used to create a multisampled 2D texture + bool SupportsMS; + + /// Initializes the structure with default values + explicit TextureFormatInfoExt() : + Filterable(false), + ColorRenderable(false), + DepthRenderable(false), + Tex1DFmt(false), + Tex2DFmt(false), + Tex3DFmt(false), + TexCubeFmt(false), + SupportsMS(false) + {} + }; +} diff --git a/Graphics/GraphicsEngine/interface/MapHelper.h b/Graphics/GraphicsEngine/interface/MapHelper.h new file mode 100644 index 00000000..9f2aae72 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/MapHelper.h @@ -0,0 +1,148 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::MapHelper helper template class + +#include "DebugUtilities.h" + +namespace Diligent +{ + +/// Facilitates resource mapping + +/// \tparam DataType - type of the mapped data. +/// +/// This class is designed to automate resource mapping/unmapping process. +/// The class automatically unmaps the resource when the class instance gets out of scope.\n +/// Usage example: +/// +/// { +/// MapHelper<float> UniformData( pDeviceContext, pUniformBuff, MAP_WRITE_DISCARD, 0 ); +/// UniformData[0] = UniformData[1] = UniformData[2] = UniformData[3] = 1; +/// } +template<typename DataType> +class MapHelper +{ +public: + + /// Initializes the class member with null values + MapHelper() : + m_pMappedData(nullptr) + { + } + + /// Initializes the object and maps the provided resource. + /// See Map() for details. + MapHelper( IDeviceContext *pContext, IBuffer *pBuffer, MAP_TYPE MapType, Uint32 MapFlags ) : + m_pMappedData(nullptr) + { + Map(pContext, pBuffer, MapType, MapFlags); + } + + /// Move constructor: takes over resource ownership from Helper + MapHelper(MapHelper&& Helper) : + m_pBuffer( std::move(Helper.m_pBuffer) ), + m_pMappedData( std::move(Helper.m_pMappedData) ), + m_pContext( std::move(Helper.m_pContext) ) + { + Helper.m_pBuffer.Release(); + Helper.m_pContext.Release(); + Helper.m_pMappedData = nullptr; + } + + /// Move-assignement operator: takes over resource ownership from Helper + MapHelper& operator = (MapHelper&& Helper) + { + m_pBuffer = std::move(Helper.m_pBuffer); + m_pMappedData = std::move(Helper.m_pMappedData); + m_pContext = std::move( Helper.m_pContext ); + Helper.m_pBuffer.Release(); + Helper.m_pContext.Release(); + Helper.m_pMappedData = nullptr; + return *this; + } + + /// Maps the provided resource. + + /// \param pContext - Pointer to the device context to perform mapping with. + /// \param pBuffer - Pointer to the buffer interface to map. + /// \param MapType - Type of the map operation, see Diligent::MAP_TYPE for details. + /// \param MapFlags - Additional map flags, see Diligent::MAP_FLAGS. + void Map( IDeviceContext *pContext, IBuffer *pBuffer, MAP_TYPE MapType, Uint32 MapFlags ) + { + VERIFY(!m_pBuffer && !m_pMappedData && !m_pContext, "Object already mapped"); + Unmap(); + m_pContext = pContext; + m_pBuffer = pBuffer; + m_pBuffer->Map(m_pContext, MapType, MapFlags, (PVoid&)m_pMappedData); + VERIFY( m_pMappedData, "Map failed" ); + } + + /// Unamps the resource and resets the object state to default. + void Unmap() + { + if( m_pBuffer ) + { + m_pBuffer->Unmap(m_pContext); + m_pBuffer.Release(); + } + m_pContext.Release(); + m_pMappedData = nullptr; + } + + /// Converts mapped data pointer to DataType* + operator DataType* (){return m_pMappedData;} + + /// Converts mapped data pointer to const DataType* + operator const DataType* ()const{return m_pMappedData;} + + /// Operator -> + DataType* operator->() {return m_pMappedData;} + + /// Operator const -> + const DataType* operator->() const{return m_pMappedData;} + + /// Unamps the resource + ~MapHelper() + { + Unmap(); + } + +private: + MapHelper(const MapHelper&); + MapHelper& operator=(const MapHelper&); + + /// Strong auto pointer to the resource + RefCntAutoPtr<IBuffer> m_pBuffer; + + /// Strong auto pointer to the context + RefCntAutoPtr<IDeviceContext> m_pContext; + + /// Pointer to the mapped data + DataType *m_pMappedData; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/RasterizerState.h b/Graphics/GraphicsEngine/interface/RasterizerState.h new file mode 100644 index 00000000..e69bf635 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/RasterizerState.h @@ -0,0 +1,194 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRasterizerState interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +/// Fill mode + +/// [D3D11_FILL_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476131(v=vs.85).aspx +/// This enumeration determines the fill mode to use when rendering triangles and mirrows the +/// [D3D11_FILL_MODE][] enum. It is used by RasterizerStateDesc structure to define the fill mode. +enum FILL_MODE : Int32 +{ + /// Undefined fill mode. + FILL_MODE_UNDEFINED = 0, + + /// Rasterize triangles using wireframe fill. \n + /// D3D11 counterpart: D3D11_FILL_WIREFRAME. OpenGL counterpart: GL_LINE. + FILL_MODE_WIREFRAME, + + /// Rasterize triangles using solid fill. \n + /// D3D11 counterpart: D3D11_FILL_SOLID. OpenGL counterpart: GL_FILL. + FILL_MODE_SOLID, + + /// Helper value that stores the total number of fill modes in the enumeration. + FILL_MODE_NUM_MODES +}; + +/// Cull mode + +/// [D3D11_CULL_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476108(v=vs.85).aspx +/// This enumeration defines which triangles are not drawn during the rasterization and mirrows +/// [D3D11_CULL_MODE][] enum. It is used by RasterizerStateDesc structure to define the polygin cull mode. +enum CULL_MODE : Int32 +{ + /// Undefined cull mode. + CULL_MODE_UNDEFINED = 0, + + /// Draw all triangles. \n + /// D3D11 counterpart: D3D11_CULL_NONE. OpenGL counterpart: glDisable( GL_CULL_FACE ). + CULL_MODE_NONE, + + /// Do not draw triangles that are front-facing. Front- and back-facing triangles are determined + /// by the RasterizerStateDesc::FrontCounterClockwise member. \n + /// D3D11 counterpart: D3D11_CULL_FRONT. OpenGL counterpart: GL_FRONT. + CULL_MODE_FRONT, + + /// Do not draw triangles that are back-facing. Front- and back-facing triangles are determined + /// by the RasterizerStateDesc::FrontCounterClockwise member. \n + /// D3D11 counterpart: D3D11_CULL_BACK. OpenGL counterpart: GL_BACK. + CULL_MODE_BACK, + + /// Helper value that stores the total number of cull modes in the enumeration. + CULL_MODE_NUM_MODES +}; + +// {530A181E-2777-4DAA-B837-ED7D3C28418E} +static const Diligent::INTERFACE_ID IID_RasterizerState = +{ 0x530a181e, 0x2777, 0x4daa, { 0xb8, 0x37, 0xed, 0x7d, 0x3c, 0x28, 0x41, 0x8e } }; + +/// Rasterizer state description + +/// This structure describes the rasterizer state which is used in a call to +/// IRenderDevice::CreateRasterizerState() to create a rasterizer state object +struct RasterizerStateDesc : DeviceObjectAttribs +{ + /// Determines traingle fill mode, see Diligent::FILL_MODE for details. + FILL_MODE FillMode; + + /// Determines traingle cull mode, see Diligent::CULL_MODE for details. + CULL_MODE CullMode; + + /// Determines if a triangle is front- or back-facing. If this parameter is True, + /// a triangle will be considered front-facing if its vertices are counter-clockwise + /// on the render target and considered back-facing if they are clockwise. + /// If this parameter is False, the opposite is true. + Bool FrontCounterClockwise; + + /// Constant value added to the depth of a given pixel. + Int32 DepthBias; + + /// Maximum depth bias of a pixel. + /// \warning Depth bias clamp is not available in OpenGL + Float32 DepthBiasClamp; + + /// Scalar that scales the given pixel's slope before adding to the pixel's depth. + Float32 SlopeScaledDepthBias; + + /// Enable clipping based on distance. + /// \warning On DirectX this only disables clipping against far clipping plane, + /// while on OpenGL this disables clipping against both far and near clip planes. + Bool DepthClipEnable; + + /// Enable scissor-rectangle culling. All pixels outside an active scissor rectangle are culled. + Bool ScissorEnable; + + /// Specifies whether to enable line antialiasing. + Bool AntialiasedLineEnable; + + /// Initializes the structure members with default values + + /// Member | Default value + /// ----------------------|-------------- + /// FillMode | FILL_MODE_SOLID + /// CullMode | CULL_MODE_BACK + /// FrontCounterClockwise | False + /// DepthBias | 0 + /// DepthBiasClamp | 0.f + /// SlopeScaledDepthBias | 0.f + /// DepthClipEnable | True + /// ScissorEnable | False + /// AntialiasedLineEnable | False + RasterizerStateDesc() : + FillMode ( FILL_MODE_SOLID ), + CullMode ( CULL_MODE_BACK ), + FrontCounterClockwise( False ), + DepthBias ( 0 ), + DepthBiasClamp ( 0.f ), + SlopeScaledDepthBias ( 0.f ), + DepthClipEnable ( True ), + ScissorEnable ( False ), + AntialiasedLineEnable( False ) + { + } + + + /// Tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise + /// The operator ignores DeviceObjectAttribs::Name field as it does not affect + /// the rasterizer state. + bool operator == (const RasterizerStateDesc& RHS)const + { + // Name is primarily used for debug purposes and does not affect the state. + // It is ignored in comparison operation. + return // strcmp(Name, RHS.Name) == 0 && + FillMode == RHS.FillMode && + CullMode == RHS.CullMode && + FrontCounterClockwise == RHS.FrontCounterClockwise && + DepthBias == RHS.DepthBias && + DepthBiasClamp == RHS.DepthBiasClamp && + SlopeScaledDepthBias == RHS.SlopeScaledDepthBias && + DepthClipEnable == RHS.DepthClipEnable && + ScissorEnable == RHS.ScissorEnable && + AntialiasedLineEnable == RHS.AntialiasedLineEnable; + } +}; + +/// Rasterizer state interface + +/// The interface holds the rasterizer state object that can be bound to the pipeline by a call +/// to IDeviceContext::SetRasterizerState(). To create a rasterizer state, call +/// IRenderDevice::CreateRasterizerState(). +class IRasterizerState : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the rasterizer state description used to create the object + virtual const RasterizerStateDesc& GetDesc()const = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/RenderDevice.h b/Graphics/GraphicsEngine/interface/RenderDevice.h new file mode 100644 index 00000000..f8471e11 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/RenderDevice.h @@ -0,0 +1,220 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRenderDevice interface and related data structures + +#include "GraphicsTypes.h" +#include "Object.h" +#include "DeviceCaps.h" +#include "Constants.h" +#include "Buffer.h" +#include "VertexDescription.h" +#include "Shader.h" +#include "Texture.h" +#include "Sampler.h" +#include "ResourceMapping.h" +#include "TextureView.h" +#include "BufferView.h" +#include "DepthStencilState.h" +#include "RasterizerState.h" +#include "BlendState.h" + +namespace Diligent +{ + +// {F0E9B607-AE33-4B2B-B1AF-A8B2C3104022} +static const Diligent::INTERFACE_ID IID_RenderDevice = +{ 0xf0e9b607, 0xae33, 0x4b2b, { 0xb1, 0xaf, 0xa8, 0xb2, 0xc3, 0x10, 0x40, 0x22 } }; + +/** + * Render device interface + */ +class IRenderDevice : public IObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Creates a new buffer object + + /// \param [in] BuffDesc - Buffer description, see Diligent::BufferDesc for details. + /// \param [in] BuffData - Reference to a Diligent::BufferData structure that describes + /// the initialization data. To allocate space only, provide default value + /// BufferData(). Static buffers (USAGE_STATIC) must be initialized + /// at creation time. + /// \param [out] ppBuffer - Address of the memory location where the pointer to the + /// buffer interface will be stored. The function calls AddRef(), + /// so that the new buffer will contain one refernce and must be + /// released by a call to Release(). + /// + /// \remarks + /// Size of a uniform buffer (BIND_UNIFORM_BUFFER) must be multiple of 16.\n + /// Stride of a formatted buffer will be computed automatically from the format if + /// ElementByteStride member of buffer description is set to default value (0). + virtual void CreateBuffer(const BufferDesc& BuffDesc, + const BufferData& BuffData, + IBuffer **ppBuffer) = 0; + + /// Creates a new vertex description object. + + /// \param [in] LayoutDesc - Layout description, see GraphisEngine::LayoutDesc for details. + /// \param [in] pVertexShader - Pointer to the vertex shader which this input layout + /// will be used with. If layout description is not compatible + /// with the shader's input signature, the method fails. + /// \param [out] ppVertexDesc - Address of the memory location where the pointer to the + /// vertex description interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + /// \remark The same vertex description object can be used with all shaders that have + /// the same input semantic. + virtual void CreateVertexDescription( const LayoutDesc& LayoutDesc, + IShader *pVertexShader, + IVertexDescription **ppVertexDesc ) = 0; + + /// Creates a new shader object + + /// \param [in] CreationAttribs - Shader creation attributes, see + /// Diligent::ShaderCreationAttribs for details. + /// \param [out] ppShader - Address of the memory location where the pointer to the + /// shader interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + virtual void CreateShader(const ShaderCreationAttribs &CreationAttribs, + IShader **ppShader) = 0; + + /// Creates a new texture object + + /// \param [in] TexDesc - Texture description, see Diligent::TextureDesc for details. + /// \param [in] Data - Reference to a Diligent::TextureData structure that describes + /// the initialization data. To allocate space only, provide default value + /// TextureData(). Static textures (USAGE_STATIC) must be initialized + /// at creation time. + /// \param [out] ppTexture - Address of the memory location where the pointer to the + /// texture interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + /// \remarks + /// To create all mip levels, set the TexDesc.MipLevels to zero.\n + /// Multisampled resources cannot be initialzed with data when they are created. \n + /// If initial data is provided, number of subresources must exactly match the number + /// of subresources in the texture (which is the number of mip levels times the number of array slices. + /// For a 3D texture, this is just the number of mip levels). + /// For example, for a 15 x 6 x 2 2D texture array, the following array of subresources should be + /// provided: \n + /// 15x6, 7x3, 3x1, 1x1, 15x6, 7x3, 3x1, 1x1.\n + /// For a 15 x 6 x 4 3D texture, the following array of subresources should be provided:\n + /// 15x6x4, 7x3x2, 3x1x1, 1x1x1 + virtual void CreateTexture(const TextureDesc& TexDesc, + const TextureData &Data, + ITexture **ppTexture) = 0; + + /// Creates a new sampler object + + /// \param [in] SamDesc - Sampler description, see Diligent::SamplerDesc for details. + /// \param [out] ppSampler - Address of the memory location where the pointer to the + /// sampler interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + /// \remark If an application attempts to create a sampler interface with the same attributes + /// as an existing interface, the same interface will be returned. + /// \note In D3D11, 4096 unique sampler state objects can be created on a device at a time. + virtual void CreateSampler(const SamplerDesc& SamDesc, + ISampler **ppSampler) = 0; + + /// Creates a new resource mapping + + /// \param [in] MappingDesc - Resource mapping description, see Diligent::ResourceMappingDesc for details. + /// \param [out] ppMapping - Address of the memory location where the pointer to the + /// resource mapping interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + virtual void CreateResourceMapping( const ResourceMappingDesc &MappingDesc, + IResourceMapping **ppMapping ) = 0; + + /// Creates a new depth stencil state object + + /// \param [in] DSSDesc - Depth-stencil state description, see Diligent::DepthStencilStateDesc for details. + /// \param [out] ppDepthStencilState - Address of the memory location where the pointer to the + /// depth-stencil state interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + /// \remark If an application attempts to create a depth-stencil state interface with the same attributes + /// as an existing interface, the same interface will be returned. + /// \note In D3D11, 4096 unique depth-stencil state objects can be created on a device at a time. + virtual void CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, + IDepthStencilState **ppDepthStencilState ) = 0; + + /// Creates a rasterizer state object + + /// \param [in] RSDesc - Rasterizer state description, see Diligent::RasterizerStateDesc for details. + /// \param [out] ppRasterizerState - Address of the memory location where the pointer to the + /// rasterizer state interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + /// \remark If an application attempts to create a rasterizer state interface with the same attributes + /// as an existing interface, the same interface will be returned. + /// \note In D3D11, 4096 unique rasterizer state objects can be created on a device at a time. + virtual void CreateRasterizerState( const RasterizerStateDesc &RSDesc, + IRasterizerState **ppRasterizerState ) = 0; + + /// Creates a blend state object + + /// \param [in] BSDesc - Blend state description, see Diligent::BlendStateDesc for details. + /// \param [out] ppBlendState - Address of the memory location where the pointer to the + /// blend state interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + /// \remark If an application attempts to create a blend state interface with the same attributes + /// as an existing interface, the same interface will be returned. + /// \note In D3D11, 4096 unique blend state objects can be created on a device at a time. + virtual void CreateBlendState( const BlendStateDesc &BSDesc, + IBlendState **ppBlendState ) = 0; + + /// Gets the device capabilities, see Diligent::DeviceCaps for details + virtual const DeviceCaps& GetDeviceCaps()const = 0; + + /// Returns the basic texture format information. + + /// See Diligent::TextureFormatInfo for details on the provided information. + /// \param [in] TexFormat - Texture format for which to provide the information + /// \return Const reference to the TextureFormatInfo structure containing the + /// texture format description. + virtual const TextureFormatInfo &GetTextureFormatInfo( TEXTURE_FORMAT TexFormat ) = 0; + + + /// Returns the extended texture format information. + + /// See Diligent::TextureFormatInfoExt for details on the provided information. + /// \param [in] TexFormat - Texture format for which to provide the information + /// \return Const reference to the TextureFormatInfoExt structure containing the + /// extended texture format description. + /// \remark The first time this method is called for a particular format, it may be + /// considerably slower than GetTextureFormatInfo(). If you do not require + /// extended information, call GetTextureFormatInfo() instead. + virtual const TextureFormatInfoExt &GetTextureFormatInfoExt( TEXTURE_FORMAT TexFormat ) = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/ResourceMapping.h b/Graphics/GraphicsEngine/interface/ResourceMapping.h new file mode 100644 index 00000000..f4ee7a17 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/ResourceMapping.h @@ -0,0 +1,118 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IResourceMapping interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + // {6C1AC7A6-B429-4139-9433-9E54E93E384A} + static const Diligent::INTERFACE_ID IID_ResourceMapping = + { 0x6c1ac7a6, 0xb429, 0x4139, { 0x94, 0x33, 0x9e, 0x54, 0xe9, 0x3e, 0x38, 0x4a } }; + + /// Describes the resourse mapping object entry + struct ResourceMappingEntry + { + /// Object name + const Char* Name; + + /// Pointer to the object's interface + IDeviceObject *pObject; + + /// Initializes the structure members + + /// \param [in] InitName - Object name. Default value is nullptr + /// \param [in] pInitObject - Pointer to the object. Default value is nullptr + ResourceMappingEntry( const Char* InitName = nullptr, IDeviceObject *pInitObject = nullptr) : + Name( InitName ), + pObject( pInitObject ) + {} + }; + + /// Resource mapping description + struct ResourceMappingDesc + { + /// Pointer to the array of resource mapping entries. + /// The last element in the array must be default value + /// created by ResourceMappingEntry::ResourceMappingEntry() + ResourceMappingEntry *pEntries; + + /// Initializes the structure members with default values + + /// Member | Default value + /// ----------------------|-------------- + /// pEntries | nullptr + ResourceMappingDesc() : pEntries( nullptr ){} + }; + + /// Resouce mapping + + /// This interface provides mapping between literal names and resource pointers. + /// It is created by IRenderDevice::CreateResourceMapping(). + /// \remarks Resource mapping holds strong references to all objects it keeps. + class IResourceMapping : public IObject + { + public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Adds a resource to the mapping. + + /// \param [in] Name - Resource name. + /// \param [in] pObject - Pointer to the object. + /// \param [in] bIsUnique - Flag indicating if a resource with the same name + /// is allowed to be found in the mapping. In the latter + /// case, the new resource replaces the existing one. + /// + /// \remarks Resource mapping increases the reference counter for referenced objects. So an + /// object will not be released as long as it is in the resource mapping. + virtual void AddResource( const Char *Name, IDeviceObject *pObject, bool bIsUnique ) = 0; + + /// Removes a resource from the mapping. + + /// \param [in] pObject - Pointer to the object to remove. + virtual void RemoveResource( IDeviceObject *pObject ) = 0; + + /// Removes a resource from the mapping using its literal name. + + /// \param [in] Name - Name of the resource to remove. + virtual void RemoveResourceByName( const Char *Name ) = 0; + + /// Finds a resource in the mapping. + + /// \param [in] Name - Resource name. + /// \param [out] ppResource - Address of the memory location where the pointer + /// to the object with the given name will be written. + /// If no object is found, nullptr will be written. + /// \remarks The method increases the reference counter + /// of the returned object, so Release() must be called. + virtual void GetResource( const Char *Name, IDeviceObject **ppResource ) = 0; + + /// Returns the size of the resource mapping, i.e. the number of objects. + virtual size_t GetSize() = 0; + }; +} diff --git a/Graphics/GraphicsEngine/interface/Sampler.h b/Graphics/GraphicsEngine/interface/Sampler.h new file mode 100644 index 00000000..52742b3c --- /dev/null +++ b/Graphics/GraphicsEngine/interface/Sampler.h @@ -0,0 +1,174 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ISampler interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +// {595A59BF-FA81-4855-BC5E-C0E048745A95} +static const Diligent::INTERFACE_ID IID_Sampler = +{ 0x595a59bf, 0xfa81, 0x4855, { 0xbc, 0x5e, 0xc0, 0xe0, 0x48, 0x74, 0x5a, 0x95 } }; + +/// Sampler description + +/// This structure describes the sampler state which is used in a call to +/// IRenderDevice::CreateSampler() to create a sampler object. +/// +/// To create an anisotropic filter, all three filters must either be Diligent::FILTER_TYPE_ANISOTROPIC +/// or Diligent::FILTER_TYPE_COMPARISON_ANISOTROPIC. +/// +/// MipFilter cannot be comparison filter except for Diligent::FILTER_TYPE_ANISOTROPIC if all +/// three filters have that value. +/// +/// Both MinFilter and MagFilter must either be regular filters or comparison filters. +/// Mixing comparison and regular filters is an error. +struct SamplerDesc : DeviceObjectAttribs +{ + /// Texture minification filter, see Diligent::FILTER_TYPE for details. + FILTER_TYPE MinFilter; + + /// Texture magnification filter, see Diligent::FILTER_TYPE for details. + FILTER_TYPE MagFilter; + + /// Mip filter, see Diligent::FILTER_TYPE for details. + /// Only FILTER_TYPE_POINT, FILTER_TYPE_LINEAR, FILTER_TYPE_ANISOTROPIC, and + /// FILTER_TYPE_COMPARISON_ANISOTROPIC are allowed. + FILTER_TYPE MipFilter; + + /// Texture address mode for U coordinate, see Diligent::TEXTURE_ADDRESS_MODE for details + TEXTURE_ADDRESS_MODE AddressU; + + /// Texture address mode for V coordinate, see Diligent::TEXTURE_ADDRESS_MODE for details + TEXTURE_ADDRESS_MODE AddressV; + + /// Texture address mode for W coordinate, see Diligent::TEXTURE_ADDRESS_MODE for details + TEXTURE_ADDRESS_MODE AddressW; + + /// Offset from the calculated mipmap level. For example, if a sampler calculates that a texture + /// should be sampled at mipmap level 1.2 and MipLODBias is 2.3, then the texture will be sampled at + /// mipmap level 3.5. + Float32 MipLODBias; + + /// Maximum anisotropy level for the anisotropic filter. + Uint32 MaxAnisotropy; + + /// A function that compares sampled data against existing sampled data when comparsion + /// filter is used. + COMPARISON_FUNCTION ComparisonFunc; + + /// Border color to use if TEXTURE_ADDRESS_BORDER is specified for AddressU, AddressV, or AddressW. + Float32 BorderColor[4]; + + /// Specifies the minimum value that LOD is clamped to before accessing the texture MIP levels. + /// Must be less than or equal to MaxLOD. + float MinLOD; + + /// Specifies the maximum value that LOD is clamped to before accessing the texture MIP levels. + /// Must be greater than or equal to MinLOD. + float MaxLOD; + + /// Initializes the structure members with default values + + /// Member | Default value + /// --------------------|-------------- + /// MinFilter | FILTER_TYPE_LINEAR + /// MagFilter | FILTER_TYPE_LINEAR + /// MipFilter | FILTER_TYPE_LINEAR + /// AddressU | TEXTURE_ADDRESS_CLAMP + /// AddressV | TEXTURE_ADDRESS_CLAMP + /// AddressW | TEXTURE_ADDRESS_CLAMP + /// MipLODBias | 0 + /// MaxAnisotropy | 0 + /// ComparisonFunc | COMPARISON_FUNC_NEVER + /// BorderColor | (0,0,0,0) + /// MinLOD | 0 + /// MaxLOD | +FLT_MAX + SamplerDesc() : + MinFilter(FILTER_TYPE_LINEAR), + MagFilter(FILTER_TYPE_LINEAR), + MipFilter(FILTER_TYPE_LINEAR), + AddressU(TEXTURE_ADDRESS_CLAMP), + AddressV(TEXTURE_ADDRESS_CLAMP), + AddressW(TEXTURE_ADDRESS_CLAMP), + MipLODBias(0), + MaxAnisotropy(0), + ComparisonFunc(COMPARISON_FUNC_NEVER), + MinLOD(0), + MaxLOD(+FLT_MAX) + { + BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 0; + } + + /// Tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise. + /// The operator ignores DeviceObjectAttribs::Name field as it does not affect + /// the sampler state. + bool operator ==(const SamplerDesc& RHS)const + { + // Name is primarily used for debug purposes and does not affect the state. + // It is ignored in comparison operation. + return // strcmp(Name, RHS.Name) == 0 && + MinFilter == RHS.MinFilter && + MagFilter == RHS.MagFilter && + MipFilter == RHS.MipFilter && + AddressU == RHS.AddressU && + AddressV == RHS.AddressV && + AddressW == RHS.AddressW && + MipLODBias == RHS.MipLODBias && + MaxAnisotropy == RHS.MaxAnisotropy && + ComparisonFunc == RHS.ComparisonFunc && + BorderColor[0] == RHS.BorderColor[0] && + BorderColor[1] == RHS.BorderColor[1] && + BorderColor[2] == RHS.BorderColor[2] && + BorderColor[3] == RHS.BorderColor[3] && + MinLOD == RHS.MinLOD && + MaxLOD == RHS.MaxLOD; + } +}; + +/// Texture sampler interface. + +/// The interface holds the sampler state that can be used to perform texture filtering. +/// To create a sampler, call IRenderDevice::CreateSampler(). To use a sampler, +/// call ITextureView::SetSampler(). +class ISampler : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the sampler description used to create the object + virtual const SamplerDesc& GetDesc()const = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h new file mode 100644 index 00000000..61861648 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -0,0 +1,208 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IShader interface and related data structures + +#include "DeviceObject.h" +#include "ResourceMapping.h" +#include "FileStream.h" + +namespace Diligent +{ + +// {2989B45C-143D-4886-B89C-C3271C2DCC5D} +static const Diligent::INTERFACE_ID IID_Shader = +{ 0x2989b45c, 0x143d, 0x4886, { 0xb8, 0x9c, 0xc3, 0x27, 0x1c, 0x2d, 0xcc, 0x5d } }; + +// {0D57DF3F-977D-4C8F-B64C-6675814BC80C} +static const Diligent::INTERFACE_ID IID_ShaderVariable = +{ 0xd57df3f, 0x977d, 0x4c8f, { 0xb6, 0x4c, 0x66, 0x75, 0x81, 0x4b, 0xc8, 0xc } }; + +/// Describes the shader type +enum SHADER_TYPE : Int32 +{ + SHADER_TYPE_UNKNOWN = 0x000, ///< Unknown shader type + SHADER_TYPE_VERTEX = 0x001, ///< Vertex shader + SHADER_TYPE_PIXEL = 0x002, ///< Pixel (fragment) shader + SHADER_TYPE_GEOMETRY = 0x004, ///< Geometry shader + SHADER_TYPE_HULL = 0x008, ///< Hull (tessellation control) shader + SHADER_TYPE_DOMAIN = 0x010, ///< Domain (tessellation evaluation) shader + SHADER_TYPE_COMPUTE = 0x020 ///< Compute shader +}; + +enum SHADER_PROFILE : Int32 +{ + SHADER_PROFILE_DEFAULT = 0, + SHADER_PROFILE_DX_4_0, + SHADER_PROFILE_DX_5_0, + SHADER_PROFILE_GL_4_2 +}; + +enum SHADER_SOURCE_LANGUAGE : Int32 +{ + SHADER_SOURCE_LANGUAGE_DEFAULT = 0, + SHADER_SOURCE_LANGUAGE_HLSL, + SHADER_SOURCE_LANGUAGE_GLSL +}; + +/// Describes flags that can be supplied to IShader::BindResources() +/// and IDeviceContext::BindShaderResources(). +enum BIND_SHADER_RESOURCES_FLAGS : Int32 +{ + /// Reset all bindings. If this specified, all existing bindings will be + /// broken. By default all existing bindings are presereved. + BIND_SHADER_RESOURCES_RESET_BINDINGS = 0x01, + + /// If this flag is specified, only unresolved bindings will be updated. + /// All resolved bindings will keep their original values. + /// If this flag is not specified, every shader variable will be + /// updated if the mapping contains corresponding resource. + BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED = 0x02, + + /// If this flag is specified, all shader bindings are expected + /// to be resolved after the call. If this is not the case, debug error + /// will be output. + BIND_SHADER_RESOURCES_ALL_RESOLVED = 0x04 +}; + +/// Shader description +struct ShaderDesc : DeviceObjectAttribs +{ + /// Shader type. See Diligent::SHADER_TYPE + SHADER_TYPE ShaderType; + + Bool bCacheCompiledShader; + SHADER_PROFILE TargetProfile; + + ShaderDesc() : + ShaderType(SHADER_TYPE_VERTEX), + bCacheCompiledShader(False), + TargetProfile(SHADER_PROFILE_DEFAULT) + {} +}; + +/// Shader source stream factory interface +class IShaderSourceInputStreamFactory +{ +public: + virtual void CreateInputStream(const Diligent::Char *Name, IFileStream **ppStream) = 0; +}; + +struct ShaderMacro +{ + const Char* Name; + const Char* Definition; + ShaderMacro(const Char* _Name, const Char* _Def) : Name( _Name ), Definition( _Def ) {} +}; + +/// Shader creation attributes +struct ShaderCreationAttribs +{ + /// Source file path + const Char* FilePath; + + /// Pointer to the shader source input stream factory. + /// The factory is used to create additional input streams for + /// shader include files + IShaderSourceInputStreamFactory *pShaderSourceStreamFactory; + + /// Shader source + const Char* Source; + + /// Shader entry point + const Char* EntryPoint; + + /// Semicolon-separated list of include search directories. + const Char* SearchDirectories; + + /// Shader macros + const ShaderMacro *Macros; + + /// Shader description. See Diligent::ShaderDesc. + ShaderDesc Desc; + + /// Shader source language. See Diligent::SHADER_SOURCE_LANGUAGE. + SHADER_SOURCE_LANGUAGE SourceLanguage; + + ShaderCreationAttribs() : + FilePath( nullptr ), + Source( nullptr ), + pShaderSourceStreamFactory( nullptr ), + EntryPoint("main"), + SearchDirectories(nullptr), + Macros(nullptr), + SourceLanguage(SHADER_SOURCE_LANGUAGE_DEFAULT) + {} +}; + + +/// Shader resource variable +class IShaderVariable : public IObject +{ +public: + /// Sets the variable to the given value + + /// \remark The method performs run-time correctness checks. + /// For instance, shader resource view cannot + /// be assigned to a constant buffer variable. + virtual void Set(IDeviceObject *pObject) = 0; + + /// Returns the shader which this shader variable + /// belongs to + + /// \remark The method does not increment the reference counter + /// of the returned interface. + virtual class IShader* GetShader() = 0; +}; + +/// Shader interface +class IShader : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the shader description + virtual const ShaderDesc &GetDesc()const = 0; + + /// Binds shader resources. + /// \param [in] pResourceMapping - Pointer to IResourceMapping interface to + /// look for resources. + /// \param [in] Flags - Additional flags for the operation. See + /// Diligent::BIND_SHADER_RESOURCES_FLAGS for details. + /// \remark The shader will keep strong references to all resources bound to it. + virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags ) = 0; + + /// Returns an interface to a shader variable. If the shader variable + /// is not found, an interface to a dummy variable will be returned. + + /// \param [in] Name - Name of the variable. + /// \remark The method does not increment the reference counter + /// of the returned interface. + virtual IShaderVariable* GetShaderVariable(const Char* Name) = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/SwapChain.h b/Graphics/GraphicsEngine/interface/SwapChain.h new file mode 100644 index 00000000..c451bbf6 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/SwapChain.h @@ -0,0 +1,58 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ISwapChain interface and related data structures + +#include "Object.h" + +namespace Diligent +{ + +// {1C703B77-6607-4EEC-B1FE-15C82D3B4130} +static const Diligent::INTERFACE_ID IID_SwapChain = +{ 0x1c703b77, 0x6607, 0x4eec, { 0xb1, 0xfe, 0x15, 0xc8, 0x2d, 0x3b, 0x41, 0x30 } }; + +/// Swap chain interface + +/// The swap chain is created by a platform-dependent function +class ISwapChain : public IObject +{ +public: + + /// Presents a rendered image to the user. + virtual void Present() = 0; + + /// Returns the swap chain desctription + virtual const SwapChainDesc& GetDesc()const = 0; + + /// Changes the swap chain's back buffer size + + /// \param [in] NewWidth - New swap chain width, in pixels + /// \param [in] NewHeight - New swap chain height, in pixels + virtual void Resize( Uint32 NewWidth, Uint32 NewHeight ) = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/Texture.h b/Graphics/GraphicsEngine/interface/Texture.h new file mode 100644 index 00000000..de352a3c --- /dev/null +++ b/Graphics/GraphicsEngine/interface/Texture.h @@ -0,0 +1,254 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ITexture interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +// {A64B0E60-1B5E-4CFD-B880-663A1ADCBE98} +static const Diligent::INTERFACE_ID IID_Texture = +{ 0xa64b0e60, 0x1b5e, 0x4cfd, { 0xb8, 0x80, 0x66, 0x3a, 0x1a, 0xdc, 0xbe, 0x98 } }; + +/// Texture description +struct TextureDesc : DeviceObjectAttribs +{ + /// Texture type. See Diligent::TEXTURE_TYPE for details. + TEXTURE_TYPE Type; + + /// Texture width, in pixels. + Uint32 Width; + + /// Texture height, in pixels. + Uint32 Height; + union + { + /// For a 1D array or 2D array, number of array slices + Uint32 ArraySize; + + /// For a 3D texture, number of depth slices + Uint32 Depth; + }; + + /// Texture format, see Diligent::TEXTURE_FORMAT. + TEXTURE_FORMAT Format; + + /// Number of Mip levels in the texture. Multisampled textures can only have 1 Mip level. + /// Specify 0 to generate full mipmap chain. + Uint32 MipLevels; + + /// Number of samples.\n + /// Only 2D textures or 2D texture arrays can be multisampled. + Uint32 SampleCount; + + /// Texture usage. See Diligent::USAGE for details. + USAGE Usage; + + /// Bind flags, see Diligent::BIND_FLAGS for details. \n + /// The following bind flags are allowed: + /// Diligent::BIND_SHADER_RESOURCE, Diligent::BIND_RENDER_TARGET, Diligent::BIND_DEPTH_STENCIL, + /// Diligent::and BIND_UNORDERED_ACCESS. \n + /// Multisampled textures cannot have Diligent::BIND_UNORDERED_ACCESS flag set + Uint32 BindFlags; + + /// CPU access flags or 0 if no CPU access is allowed, + /// see Diligent::CPU_ACCESS_FLAG for details. + Uint32 CPUAccessFlags; + + + /// Miscellaneous flags, see Diligent::MISC_TEXTURE_FLAG for details. + Uint32 MiscFlags; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// ----------------|-------------- + /// Type | TEXTURE_TYPE_UNDEFINED + /// Width | 0 + /// Height | 0 + /// ArraySize | 1 + /// Format | TEX_FORMAT_UNKNOWN + /// MipLevels | 1 + /// SampleCount | 1 + /// Usage | USAGE_DEFAULT + /// BindFlags | 0 + /// CPUAccessFlags | 0 + /// MiscFlags | 0 + TextureDesc() : + Type(TEXTURE_TYPE_UNDEFINED), + Width(0), + Height(0), + ArraySize(1), + Format(TEX_FORMAT_UNKNOWN), + MipLevels(1), + SampleCount(1), + Usage(USAGE_DEFAULT), + BindFlags(0), + CPUAccessFlags(0), + MiscFlags(0) + { + } +}; + +/// Describes data for one subresource +struct TextureSubResData +{ + /// Pointer to the subresource data + const void* pData; + + /// For 2D and 3D textures, row stride in bytes + Uint32 Stride; + + /// For 3D textures, depth slice stride in bytes + /// \note On OpenGL, this must be a mutliple of Stride + Uint32 DepthStride; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// ----------------|-------------- + /// pData | nullptr + /// Stride | 0 + /// DepthStride | 0 + TextureSubResData(): + pData(nullptr), + Stride(0), + DepthStride(0) + {} +}; + +/// Describes the initial data to store in the texture +struct TextureData +{ + /// Pointer to the array of the TextureSubResData elements containing + /// information about each subresource. + TextureSubResData *pSubResources; + + /// Number of elements in pSubResources array. + /// NumSubresources must exactly match the number + /// of subresources in the texture. Otherwise an error + /// occurs. + Uint32 NumSubresources; + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// ----------------|-------------- + /// pSubResources | nullptr + /// NumSubresources | 0 + TextureData() : + pSubResources(nullptr), + NumSubresources(0) + {} +}; + +/// Texture inteface +class ITexture : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the texture description used to create the object + virtual const TextureDesc& GetDesc()const = 0; + + /// Creates a new texture view + + /// \param [in] ViewDesc - View description. See Diligent::TextureViewDesc for details. + /// \param [out] ppView - Address of the memory location where the pointer to the view interface will be written to. + /// + /// \remarks To create a shader resource view addressing the entire texture, set only TextureViewDesc::ViewType + /// member of the ViewDesc parameter to Diligent::TEXTURE_VIEW_SHADER_RESOURCE and leave all other + /// members in their default values. Using the same method, you can create render target or depth stencil + /// view addressing the largest mip level.\n + /// If texture view format is Diligent::TEX_FORMAT_UNKNOWN, the view format will match the texture format.\n + /// If texture view type is Diligent::TEXTURE_VIEW_UNDEFINED, the type will match the texture type.\n + /// If the number of mip levels is 0, and the view type is shader resource, the view will address all mip levels. + /// For other view types it will address one mip level.\n + /// If the number of slices is 0, all slices from FirstArraySlice or FirstDepthSlice will be referenced by the view. + /// For non-array textures, the only allowed values for the number of slices are 0 and 1.\n + /// Texture view will contain strong reference to the texture, so the texture will not be destroyed + /// until all views are released.\n + /// The function calls AddRef() for the created interface, so it must be released by + /// a call to Release() when it is no longer needed. + virtual void CreateView(const struct TextureViewDesc &ViewDesc, class ITextureView **ppView) = 0; + + /// Returns the pointer to the default view. + + /// \param [in] ViewType - Type of the requested view. See Diligent::TEXTURE_VIEW_TYPE. + /// \return Pointer to the interface + /// + /// \note The function does not increase the reference counter for the returned interface, so + /// Release() must *NOT* be called. + virtual ITextureView* GetDefaultView( TEXTURE_VIEW_TYPE ViewType ) = 0; + + /// Updates the data in the texture + + /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation. + /// \param [in] MipLevel - Mip level of the texture subresource to update. + /// \param [in] Slice - Array slice. Should be 0 for non-array textures. + /// \param [in] DstBox - Destination region on the texture to update. + /// \param [in] SubresData - Source data to copy to the texture. + virtual void UpdateData( class IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) = 0; + + /// Copies data from another texture + + /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation. + /// \param [in] pSrcTexture - Source texture for the copy operation + /// \param [in] SrcMipLevel - Mip level of the source texture to copy data from. + /// \param [in] SrcSlice - Array slice of the source texture to copy data from. + /// Should be 0 for non-array textures. + /// \param [in] pSrcBox - Source region to copy. + /// Use nullptr to copy the entire subresource. + /// \param [in] DstMipLevel - Mip level to copy data to. + /// \param [in] DstSlice - Array slice to copy data to. + /// Must be 0 for non-array textures. + /// \param [in] DstX - X offset on the destination subresource + /// \param [in] DstY - Y offset on the destination subresource + /// \param [in] DstZ - Z offset on the destination subresource + virtual void CopyData(IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ) = 0; + + /// Map the texture - not implemented yet + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) = 0; + /// Unmap the textute - not implemented yet + virtual void Unmap( IDeviceContext *pContext ) = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/TextureView.h b/Graphics/GraphicsEngine/interface/TextureView.h new file mode 100644 index 00000000..b55e2f0e --- /dev/null +++ b/Graphics/GraphicsEngine/interface/TextureView.h @@ -0,0 +1,198 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ITextureView interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +// {5B2EA04E-8128-45E4-AA4D-6DC7E70DC424} +static const Diligent::INTERFACE_ID IID_TextureView = +{ 0x5b2ea04e, 0x8128, 0x45e4, { 0xaa, 0x4d, 0x6d, 0xc7, 0xe7, 0xd, 0xc4, 0x24 } }; + +/// Describes allowed unordered access view mode +enum UAV_ACCESS_FLAG : Int32 +{ + /// Access mode is unspecified + UAV_ACCESS_UNSPECIFIED = 0x00, + + /// Allow read operations on the UAV + UAV_ACCESS_FLAG_READ = 0x01, + + /// Allow write operations on the UAV + UAV_ACCESS_FLAG_WRITE = 0x02, + + /// Allow read and write operations on the UAV + UAV_ACCESS_FLAG_READ_WRITE = UAV_ACCESS_FLAG_READ | UAV_ACCESS_FLAG_WRITE +}; + +/// Texture view description +struct TextureViewDesc : DeviceObjectAttribs +{ + /// Describes the texture view type, see Diligent::TEXTURE_VIEW_TYPE for details. + TEXTURE_VIEW_TYPE ViewType; + + /// View interpretation of the original texture. For instance, + /// one slice of a 2D texture array can be viewed as a 2D texture. + /// See Diligent::TEXTURE_TYPE for a list of texture types. + /// If default value Diligent::TEXTURE_TYPE_UNDEFINED is provided, + /// the view type will match the type of the referenced texture. + TEXTURE_TYPE TextureType; + + /// View format. If default value Diligent::TEX_FORMAT_UNKNOWN is provided, + /// the view format will match the referenced texture format. + TEXTURE_FORMAT Format; + + /// Most detailed mip level to use + Uint32 MostDetailedMip; + + /// Total number of mip levels for the view of the texture. + /// Render target and depth stencil views can address only one mip level. + /// If 0 is provided, then for a shader resource view all mip levels will be + /// referenced, and for a render target or a depth stencil view, one mip level + /// will be referenced. + Uint32 NumMipLevels; + + union + { + /// For a texture array, first array slice to address in the view + Uint32 FirstArraySlice; + + /// For a 3D texture, first depth slice to address the view + Uint32 FirstDepthSlice; + }; + + union + { + /// For a texture array, number of array slices to address in the view. + /// Set to 0 to address all array slices. + Uint32 NumArraySlices; + + /// For a 3D texture, number of depth slices to address in the view + /// Set to 0 to address all depth slices. + Uint32 NumDepthSlices; + }; + + /// For an unordered access view, allowed access flags. See Diligent::UAV_ACCESS_FLAG + /// for details. + Uint32 AccessFlags; + + + /// Initializes the structure members with default values + + /// Default values: + /// Member | Default value + /// --------------------|-------------- + /// ViewType | TEXTURE_VIEW_UNDEFINED + /// TextureType | TEXTURE_TYPE_UNDEFINED + /// Format | TEX_FORMAT_UNKNOWN + /// MostDetailedMip | 0 + /// NumMipLevels | 0 + /// FirstArraySlice | 0 + /// NumArraySlices | 0 + /// AccessFlags | 0 + TextureViewDesc() : + ViewType( TEXTURE_VIEW_UNDEFINED ), + TextureType( TEXTURE_TYPE_UNDEFINED ), + Format(TEX_FORMAT_UNKNOWN), + MostDetailedMip(0), + NumMipLevels(0), + FirstArraySlice(0), + NumArraySlices(0), + AccessFlags(0) + { + } + + /// Tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise + bool operator == (const TextureViewDesc& RHS)const + { + // Name is primarily used for debug purposes and does not affect the view. + // It is ignored in comparison operation. + return //strcmp(Name, RHS.Name) == 0 && + ViewType == RHS.ViewType && + TextureType == RHS.TextureType && + Format == RHS.Format && + MostDetailedMip == RHS.MostDetailedMip && + NumMipLevels == RHS.NumMipLevels && + FirstArraySlice == RHS.FirstArraySlice && + FirstDepthSlice == RHS.FirstDepthSlice && + NumArraySlices == RHS.NumArraySlices && + NumDepthSlices == RHS.NumDepthSlices && + AccessFlags == RHS.AccessFlags; + } +}; + +/// Texture view interface + +/// \remarks +/// To create a texture view, call ITexture::CreateView(). +/// Texture view holds strong references to the texture. The texture +/// will not be destroyed until all views are released. +/// The texture view will also keep a strong reference to the texture sampler, +/// if any is set. +class ITextureView : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the texture view description used to create the object + virtual const TextureViewDesc& GetDesc()const = 0; + + /// Sets the texture sampler to use for filtering operations + /// when accessing a texture from shaders. Only + /// shader resource views can be assigned a sampler. + /// The view will keep strong reference to the sampler. + virtual void SetSampler( class ISampler *pSampler ) = 0; + + /// Returns the pointer to the sampler object set by the ITextureView::SetSampler(). + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ISampler* GetSampler() = 0; + + + /// Returns the pointer to the referenced texture object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual class ITexture* GetTexture() = 0; + + /// Generates a mipmap chain + + /// \remarks This function can only be called for a shader resource view + /// The texture must be created with MISC_TEXTURE_FLAG_GENERATE_MIPS flag + virtual void GenerateMips(IDeviceContext *pContext ) = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/VertexDescription.h b/Graphics/GraphicsEngine/interface/VertexDescription.h new file mode 100644 index 00000000..4883ab40 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/VertexDescription.h @@ -0,0 +1,140 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IVertexDescription interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +// {2D6915E5-003B-4C68-BDF0-8F93FA7AD4BC} +static const Diligent::INTERFACE_ID IID_VertexDescription = +{ 0x2d6915e5, 0x3b, 0x4c68, { 0xbd, 0xf0, 0x8f, 0x93, 0xfa, 0x7a, 0xd4, 0xbc } }; + +static const Uint32 iMaxLayoutElements = 16; + +/// Description of a single element of the input layout +struct LayoutElement +{ + /// Input index of the element, which is specified in the vertex shader. + Uint32 InputIndex; + + /// Buffer slot index that this element is read from. + Uint32 BufferSlot; + + /// Number of components in the element. Allowed values are 1, 2, 3, and 4. + Uint32 NumComponents; + + /// Type of the element components, see Diligent::VALUE_TYPE for details. + VALUE_TYPE ValueType; + + /// For signed and unsigned integer value types + /// (VT_INT8, VT_INT16, VT_INT32, VT_UINT8, VT_UINT16, VT_UINT32) + /// indicates if the value should be normalized to [-1,+1] or + /// [0, 1] range respectively. For floating point types + /// (VT_FLOAT16 and VT_FLOAT32), this member is ignored. + Bool IsNormalized; + + /// Relative offset, in bytes, to the element bits. + /// If this value is zero, the offset will be computed automatically + /// assuming that all previous elements in the same buffer slot a tightly packed. + /// Overlapping elements are not allowed. + Uint32 RelativeOffset; + + /// Input frequency + enum FREQUENCY : Int32 + { + /// Frequency is undefined. + FREQUENCY_UNDEFINED = 0, + + /// Input data is per-vertex data. + FREQUENCY_PER_VERTEX, + + /// Input data is per-instance data. + FREQUENCY_PER_INSTANCE, + + /// Helper value that stores the total number of frequencies in the enumeration. + FREQUENCY_NUM_FREQUENCIES + }Frequency; + + /// The number of instances to draw using the same per-instance data before advancing + /// in the buffer by one element. + Uint32 InstanceDataStepRate; + + /// Initializes the structure + LayoutElement(Uint32 _InputIndex = 0, + Uint32 _BufferSlot = 0, + Uint32 _NumComponents = 0, + VALUE_TYPE _ValueType = VT_FLOAT32, + Bool _IsNormalized = True, + Uint32 _RelativeOffset = 0, + FREQUENCY _Frequency = FREQUENCY_PER_VERTEX, + Uint32 _InstanceDataStepRate = 1) : + InputIndex(_InputIndex), + BufferSlot(_BufferSlot), + NumComponents(_NumComponents), + ValueType(_ValueType), + IsNormalized(_IsNormalized), + RelativeOffset(_RelativeOffset), + Frequency(_Frequency), + InstanceDataStepRate(_InstanceDataStepRate) + {} +}; + +/// Layout description + +/// This structure is used by IRenderDevice::CreateVertexDescription(). +struct LayoutDesc : DeviceObjectAttribs +{ + /// Array of layout elements + const LayoutElement *LayoutElements; + Uint32 NumElements; + LayoutDesc() : + LayoutElements(nullptr), + NumElements(0) + {} +}; + +/// Vertex description interface + +/// Vertex description is created by a call to IRenderDevice::CreateVertexDescription(). +/// To bind vertex descption, call IDeviceContext::SetVertexDescription(). +class IVertexDescription : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns layout description used to create the object + virtual const LayoutDesc &GetDesc()const = 0; + + /// Returns tight strides for each input buffer slot. Tight strides are computed + /// assuming that all layout elements in the buffer are tightly packed. + virtual const Uint32* GetTightStrides() = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/src/ResourceMapping.cpp b/Graphics/GraphicsEngine/src/ResourceMapping.cpp new file mode 100644 index 00000000..47a54ed9 --- /dev/null +++ b/Graphics/GraphicsEngine/src/ResourceMapping.cpp @@ -0,0 +1,130 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "ResourceMappingImpl.h" +#include "DeviceObjectBase.h" + +using namespace std; + +namespace Diligent +{ + ResourceMappingImpl::~ResourceMappingImpl() + { + } + + IMPLEMENT_QUERY_INTERFACE( ResourceMappingImpl, IID_ResourceMapping, ObjectBase<IResourceMapping> ) + + ThreadingTools::LockHelper ResourceMappingImpl::Lock() + { + return std::move( ThreadingTools::LockHelper( m_LockFlag ) ); + } + + void ResourceMappingImpl::AddResource( const Char *Name, IDeviceObject *pObject, bool bIsUnique ) + { + if( Name == nullptr || *Name == 0 ) + return; + + auto LockHelper = Lock(); + // Try to construct new element in place + auto Elems = + m_HashTable.emplace( + make_pair( Diligent::HashMapStringKey(Name, true), // Make a copy of the source string + Diligent::RefCntAutoPtr<IDeviceObject>(pObject) + ) + ); + // If there is already element with the same name, replace it + if( !Elems.second && Elems.first->second != pObject ) + { + if( bIsUnique ) + { + UNEXPECTED( "Resource with the same name already exists" ); + LOG_WARNING_MESSAGE( + "Resource with name ", Name, " marked is unique, but already present in the hash.\n" + "New resource will be used\n." ); + } + Elems.first->second = pObject; + } + } + + void ResourceMappingImpl::RemoveResourceByName( const Char *Name ) + { + if( *Name == 0 ) + return; + + auto LockHelper = Lock(); + // Remove object with the given name + // Name will be implicitly converted to HashMapStringKey without making a copy + auto It = m_HashTable.erase( Name ); + } + + void ResourceMappingImpl::RemoveResource( IDeviceObject *pObject ) + { + const auto *Name = pObject->GetDesc().Name; + VERIFY( Name, "Name is null" ); + if( *Name == 0 ) + return; + + auto LockHelper = Lock(); + + // Find active object with the same name + // Name will be implicitly converted to HashMapStringKey without making a copy + auto It = m_HashTable.find( Name ); + // Check if the active object is in fact the object being removed + if( It != m_HashTable.end() && It->second == pObject ) + { + m_HashTable.erase( It ); + } + } + + void ResourceMappingImpl::GetResource( const Char *Name, IDeviceObject **ppResource ) + { + VERIFY(Name, "Name is null") + if( *Name == 0 ) + return; + + VERIFY( ppResource, "Null pointer provided" ); + if(!ppResource) + return; + + VERIFY( *ppResource == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + *ppResource = nullptr; + + auto LockHelper = Lock(); + + // Find an object with the requested name + // Name will be implicitly converted to HashMapStringKey without making a copy + auto It = m_HashTable.find( Name ); + if( It != m_HashTable.end() ) + { + *ppResource = It->second.RawPtr(); + if(*ppResource) + (*ppResource)->AddRef(); + } + } + + size_t ResourceMappingImpl::GetSize() + { + return m_HashTable.size(); + } +} diff --git a/Graphics/GraphicsEngine/src/Texture.cpp b/Graphics/GraphicsEngine/src/Texture.cpp new file mode 100644 index 00000000..60440bdc --- /dev/null +++ b/Graphics/GraphicsEngine/src/Texture.cpp @@ -0,0 +1,191 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "Texture.h" + +namespace Diligent +{ + +void ValidateTextureDesc( const TextureDesc& Desc ) +{ +#define LOG_TEXTURE_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Texture \"", Desc.Name ? Desc.Name : "", "\": ", ##__VA_ARGS__) + + // Perform some parameter correctness check + if( Desc.Type == TEXTURE_TYPE_1D || Desc.Type == TEXTURE_TYPE_1D_ARRAY ) + { + if( Desc.Height != 1 ) + LOG_TEXTURE_ERROR_AND_THROW("Height (", Desc.Height,") of Texture 1D/Texture 1D Array must be 1"); + } + + if( Desc.Type == TEXTURE_TYPE_1D || Desc.Type == TEXTURE_TYPE_2D ) + { + if( Desc.ArraySize != 1 ) + LOG_TEXTURE_ERROR_AND_THROW("Texture 1D/2D must have one array slice (", Desc.ArraySize, " provided). Use Texture 1D/2D array if you need more than one slice."); + } + + Uint32 MaxDim = 0; + if( Desc.Type == TEXTURE_TYPE_1D || Desc.Type == TEXTURE_TYPE_1D_ARRAY ) + MaxDim = Desc.Width; + else if( Desc.Type == TEXTURE_TYPE_2D || Desc.Type == TEXTURE_TYPE_2D_ARRAY ) + MaxDim = std::max(Desc.Width, Desc.Height); + else if( Desc.Type == TEXTURE_TYPE_3D ) + MaxDim = std::max( std::max(Desc.Width, Desc.Height), Desc.Depth ); + VERIFY( MaxDim >= (1U << (Desc.MipLevels-1)), "Texture \"", Desc.Name ? Desc.Name : "", "\": Incorrect number of Mip levels (", Desc.MipLevels, ")" ) + + if( Desc.SampleCount > 1 ) + { + if( !(Desc.Type == TEXTURE_TYPE_2D || Desc.Type == TEXTURE_TYPE_2D_ARRAY) ) + LOG_TEXTURE_ERROR_AND_THROW("Only Texture 2D/Texture 2D Array can be multisampled"); + + if( Desc.MipLevels != 1 ) + LOG_TEXTURE_ERROR_AND_THROW("Multisampled textures must have one mip level (", Desc.MipLevels, " levels specified)"); + + if( Desc.BindFlags & BIND_UNORDERED_ACCESS ) + LOG_TEXTURE_ERROR_AND_THROW("UAVs are not allowed for multisampled resources"); + } + + if( (Desc.BindFlags & BIND_RENDER_TARGET) && + ( Desc.Format == TEX_FORMAT_R8_SNORM || Desc.Format == TEX_FORMAT_RG8_SNORM || Desc.Format == TEX_FORMAT_RGBA8_SNORM || + Desc.Format == TEX_FORMAT_R16_SNORM || Desc.Format == TEX_FORMAT_RG16_SNORM || Desc.Format == TEX_FORMAT_RGBA16_SNORM ) ) + { + const auto *FmtName = GetTextureFormatAttribs( Desc.Format ).Name; + LOG_WARNING_MESSAGE( FmtName, " texture is created with BIND_RENDER_TARGET flag set.\n" + "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero.\n" + "Use UNORM format instead." ); + } +} + + +void ValidateTextureRegion(const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box &Box) +{ +#define VERIFY_TEX_PARAMS(Expr, ...) VERIFY(Expr, "Texture \"", TexDesc.Name ? TexDesc.Name : "", "\": ", ##__VA_ARGS__) + + VERIFY_TEX_PARAMS( MipLevel < TexDesc.MipLevels, "Mip level (", MipLevel, ") is out of allowed range [0, ", TexDesc.MipLevels-1, "]" ); + VERIFY_TEX_PARAMS( Box.MinX < Box.MaxX, "Incorrect X range [",Box.MinX, ", ", Box.MaxX, ")" ); + VERIFY_TEX_PARAMS( Box.MinY < Box.MaxY, "Incorrect Y range [",Box.MinY, ", ", Box.MaxY, ")" ); + VERIFY_TEX_PARAMS( Box.MinZ < Box.MaxZ, "Incorrect Z range [",Box.MinZ, ", ", Box.MaxZ, ")" ); + + if( TexDesc.Type == TEXTURE_TYPE_1D_ARRAY || + TexDesc.Type == TEXTURE_TYPE_2D_ARRAY ) + { + VERIFY_TEX_PARAMS( Slice < TexDesc.ArraySize, "Array slice (", Slice, ") is out of range [0,", TexDesc.ArraySize-1, "]" ); + } + else + { + VERIFY_TEX_PARAMS( Slice == 0, "Array slice (", Slice, ") must be 0 for non-array textures" ); + } + + Uint32 MipWidth = std::max(TexDesc.Width >> MipLevel, 1U); + VERIFY_TEX_PARAMS( Box.MaxX <= MipWidth, "Region max X coordinate (", Box.MaxX, ") is out of allowed range [0, ", MipWidth, "]" ); + if( TexDesc.Type != TEXTURE_TYPE_1D && + TexDesc.Type != TEXTURE_TYPE_1D_ARRAY ) + { + Uint32 MipHeight = std::max(TexDesc.Height >> MipLevel, 1U); + VERIFY_TEX_PARAMS( Box.MaxY <= MipHeight, "Region max Y coordinate (", Box.MaxY, ") is out of allowed range [0, ", MipHeight, "]" ); + } + + if( TexDesc.Type == TEXTURE_TYPE_3D ) + { + Uint32 MipDepth = std::max(TexDesc.Depth >> MipLevel, 1U); + VERIFY_TEX_PARAMS( Box.MaxZ <= MipDepth, "Region max Z coordinate (", Box.MaxZ, ") is out of allowed range [0, ", MipDepth, "]" ); + } +} + +void ValidateUpdateDataParams( const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + ValidateTextureRegion(TexDesc, MipLevel, Slice, DstBox); + + VERIFY_TEX_PARAMS( (SubresData.Stride & 0x03) == 0, "Texture data stride (", SubresData.Stride, ") must be at least 32-bit aligned" ); + VERIFY_TEX_PARAMS( (SubresData.DepthStride & 0x03) == 0, "Texture data depth stride (", SubresData.DepthStride, ") must be at least 32-bit aligned" ); +} + +void VliadateCopyTextureDataParams( const TextureDesc &SrcTexDesc, Uint32 SrcMipLevel, Uint32 SrcSlice, const Box *pSrcBox, + const TextureDesc &DstTexDesc, Uint32 DstMipLevel, Uint32 DstSlice, + Uint32 DstX, Uint32 DstY, Uint32 DstZ ) +{ + Box SrcBox; + if( pSrcBox == nullptr ) + { + SrcBox.MaxX = std::max( SrcTexDesc.Width >> SrcMipLevel, 1u ); + if( SrcTexDesc.Type == TEXTURE_TYPE_1D || + SrcTexDesc.Type == TEXTURE_TYPE_1D_ARRAY ) + SrcBox.MaxY = 1; + else + SrcBox.MaxY = std::max( SrcTexDesc.Height >> SrcMipLevel, 1u ); + + if( SrcTexDesc.Type == TEXTURE_TYPE_3D ) + SrcBox.MaxZ = std::max( SrcTexDesc.Depth >> SrcMipLevel, 1u ); + else + SrcBox.MaxZ = 1; + + pSrcBox = &SrcBox; + } + ValidateTextureRegion(SrcTexDesc, SrcMipLevel, SrcSlice, *pSrcBox); + + Box DstBox; + DstBox.MinX = DstX; + DstBox.MaxX = DstBox.MinX + (pSrcBox->MaxX - pSrcBox->MinX); + DstBox.MinY = DstY; + DstBox.MaxY = DstBox.MinY + (pSrcBox->MaxY - pSrcBox->MinY); + DstBox.MinZ = DstZ; + DstBox.MaxZ = DstBox.MinZ + (pSrcBox->MaxZ - pSrcBox->MinZ); + ValidateTextureRegion(DstTexDesc, DstMipLevel, DstSlice, DstBox); +} + + +//void CTexture :: Map(MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) +//{ + //switch(MapType) + //{ + // case MAP_READ: + // VERIFY( "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read from" && m_Desc.Usage == USAGE_CPU_ACCESSIBLE); + // VERIFY( "Buffer being mapped for reading was not created with CPU_ACCESS_READ flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_READ)); + // break; + + // case MAP_WRITE: + // VERIFY( "Only buffers with usage USAGE_CPU_ACCESSIBLE can be written to" && m_Desc.Usage == USAGE_CPU_ACCESSIBLE ); + // VERIFY( "Buffer being mapped for writing was not created with CPU_ACCESS_WRITE flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE)); + // break; + + // case MAP_READ_WRITE: + // VERIFY( "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read and written" && m_Desc.Usage == USAGE_CPU_ACCESSIBLE ); + // VERIFY( "Buffer being mapped for reading & writing was not created with CPU_ACCESS_WRITE flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE)); + // VERIFY( "Buffer being mapped for reading & writing was not created with CPU_ACCESS_READ flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_READ)); + // break; + + // case MAP_WRITE_DISCARD: + // VERIFY( "Only dynamic buffers can be mapped with write discard flag" && m_Desc.Usage == USAGE_DYNAMIC ); + // VERIFY( "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE) ); + // break; + + // case MAP_WRITE_NO_OVERWRITE: + // VERIFY( "Only dynamic buffers can be mapped with write no overwrite flag" && m_Desc.Usage == USAGE_DYNAMIC ); + // VERIFY( "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" && (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE) ); + // break; + + // default: VERIFY("Unknown map type" && false); + //} +//} + +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/src/pch.cpp b/Graphics/GraphicsEngine/src/pch.cpp new file mode 100644 index 00000000..bf010b17 --- /dev/null +++ b/Graphics/GraphicsEngine/src/pch.cpp @@ -0,0 +1,31 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// stdafx.cpp : source file that includes just the standard includes +// RenderEngine.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "pch.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows/EngineRoot.props b/Graphics/GraphicsEngineD3D11/build/Windows/EngineRoot.props new file mode 100644 index 00000000..02287e9c --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/Windows/EngineRoot.props @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..</GraphicsRoot> + <ProjectRoot>..\..</ProjectRoot> + </PropertyGroup> + <PropertyGroup /> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + <BuildMacro Include="ProjectRoot"> + <Value>$(ProjectRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.props b/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.props new file mode 100644 index 00000000..db23faae --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.props @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsEngineD3D11\include;$(GraphicsRoot)\GraphicsEngineD3D11\interface;$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup /> + <ItemGroup /> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj b/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj new file mode 100644 index 00000000..7a6e1ebd --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj @@ -0,0 +1,336 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="DbgDLL|Win32"> + <Configuration>DbgDLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="DbgDLL|x64"> + <Configuration>DbgDLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="RelDLL|Win32"> + <Configuration>RelDLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="RelDLL|x64"> + <Configuration>RelDLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\..\Common\build\Windows\Common.vcxproj"> + <Project>{7380f7e6-315f-4b4e-92eb-e6aeee865298}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\..\Platforms\Basic\build\Windows\BasicPlatform.vcxproj"> + <Project>{8ada5f93-7a38-4ad8-b8f5-1ffd4d4f630c}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\..\Platforms\Windows\build\Windows\WindowsPlatform.vcxproj"> + <Project>{58f32677-436b-412a-bbf8-2b1310d82cd8}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\GraphicsEngine\build\Windows\GraphicsEngine.vcxproj"> + <Project>{052dd700-477c-4512-a7f4-b05ebef5c80e}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\GraphicsTools\build\Windows\GraphicsTools.vcxproj"> + <Project>{c6014499-0cf2-43ec-a773-a4e354fb2d74}</Project> + </ProjectReference> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FE289CC7-15D6-4A76-B9CB-F61CAB3192C9}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>GraphicsEngineD3D11</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + <Import Project="..\WindowsStore\GraphicsEngineD3D11.Shared\GraphicsEngineD3D11.Shared.vcxitems" Label="Shared" Condition="Exists('..\WindowsStore\GraphicsEngineD3D11.Shared\GraphicsEngineD3D11.Shared.vcxitems')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LibraryPath>$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LibraryPath>$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LibraryPath>$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LibraryPath>$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" /> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <Lib> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>d3d11.lib;d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>..\..\src\GraphicsEngineD3D11.def</ModuleDefinitionFile> + </Link> + <Lib> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <Lib> + <AdditionalDependencies> + </AdditionalDependencies> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>d3d11.lib;d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>..\..\src\GraphicsEngineD3D11.def</ModuleDefinitionFile> + </Link> + <Lib> + <AdditionalDependencies> + </AdditionalDependencies> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <Lib> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>d3d11.lib;d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>..\..\src\GraphicsEngineD3D11.def</ModuleDefinitionFile> + </Link> + <Lib> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <Lib> + <AdditionalDependencies> + </AdditionalDependencies> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>d3d11.lib;d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>..\..\src\GraphicsEngineD3D11.def</ModuleDefinitionFile> + </Link> + <Lib> + <AdditionalDependencies> + </AdditionalDependencies> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj.filters b/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj.filters new file mode 100644 index 00000000..9cd85105 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj.filters @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/EngineRoot.props b/Graphics/GraphicsEngineD3D11/build/WindowsStore/EngineRoot.props new file mode 100644 index 00000000..fcb891c0 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/WindowsStore/EngineRoot.props @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..\..</GraphicsRoot> + </PropertyGroup> + <PropertyGroup /> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems new file mode 100644 index 00000000..0850b1e0 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <ItemsProjectGuid>{3c22010c-99f3-4321-8f55-36da8f97a980}</ItemsProjectGuid> + <ItemsRootNamespace>GraphicsEngineD3D11</ItemsRootNamespace> + <ItemsProjectName>GraphicsEngineD3D11.Shared</ItemsProjectName> + <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectCapability Include="SourceItemsFromImports" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BlendStateD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferViewD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3DErrors.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3D11DebugUtilities.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3D11TypeConversions.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceContextD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DSStateD3D11Impl.h" /> + <CustomBuild Include="$(MSBuildThisFileDirectory)..\..\..\include\HLSLDefinitions.fxh"> + <FileType>CppHeader</FileType> + <Command>$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.fxh</Command> + <Outputs>$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + </CustomBuild> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RasterizerStateD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RenderDeviceD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SamplerD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SwapChainD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\targetver.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture1D_D3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture2D_D3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture3D_D3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureBaseD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureViewD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\VertexDescD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BlendStateD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferViewD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DepthStencilStateD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceContextD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RasterizerStateD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDeviceD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDeviceFactoryD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SamplerD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\ShaderD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SwapChainD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureViewD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\VertexDescriptionD3D11.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BlendStateD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BufferD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BufferViewD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\D3D11DebugUtilities.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\D3D11TypeConversions.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DeviceContextD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DLLMain.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DSStateD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RasterizerStateD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RenderDeviceD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RenderDeviceFactoryD3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\SamplerD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\ShaderD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\SwapChainD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture1D_D3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture2D_D3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture3D_D3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\TextureBaseD3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\TextureViewD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\VertexDescD3D11Impl.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="$(MSBuildThisFileDirectory)..\..\..\src\GraphicsEngineD3D11.def" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters new file mode 100644 index 00000000..dd1617f1 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters @@ -0,0 +1,196 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="src"> + <UniqueIdentifier>{326ec87b-f6ab-4291-a28f-631b2b240d3a}</UniqueIdentifier> + </Filter> + <Filter Include="include"> + <UniqueIdentifier>{a12cf1d4-8cb0-4360-898a-d69d16e288c5}</UniqueIdentifier> + </Filter> + <Filter Include="interface"> + <UniqueIdentifier>{e3e50068-d75b-4663-bee9-5ca137971e89}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DepthStencilStateD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceContextD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RasterizerStateD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDeviceD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDeviceFactoryD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SamplerD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\ShaderD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureViewD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\VertexDescriptionD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BlendStateD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferViewD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DSStateD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RasterizerStateD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RenderDeviceD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SamplerD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture1D_D3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture2D_D3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture3D_D3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureBaseD3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureViewD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\VertexDescD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BlendStateD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferViewD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3D11TypeConversions.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceContextD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SwapChainD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SwapChainD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\targetver.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3D11DebugUtilities.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3DErrors.h"> + <Filter>include</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RenderDeviceD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\SamplerD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\ShaderD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture1D_D3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture2D_D3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture3D_D3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\TextureBaseD3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\TextureViewD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\VertexDescD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BlendStateD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BufferD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BufferViewD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\D3D11TypeConversions.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DeviceContextD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DSStateD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RasterizerStateD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\SwapChainD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RenderDeviceFactoryD3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\D3D11DebugUtilities.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DLLMain.cpp"> + <Filter>src</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="$(MSBuildThisFileDirectory)..\..\..\src\GraphicsEngineD3D11.def"> + <Filter>src</Filter> + </None> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="$(MSBuildThisFileDirectory)..\..\..\include\HLSLDefinitions.fxh"> + <Filter>include</Filter> + </CustomBuild> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj new file mode 100644 index 00000000..095b7883 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj @@ -0,0 +1,205 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3838fd2b-3c87-4caf-95de-95e7c3947c26}</ProjectGuid> + <RootNamespace>GraphicsEngineD3D11</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <AppContainerApplication>true</AppContainerApplication> + <ApplicationType>Windows Store</ApplicationType> + <ApplicationTypeRevision>8.1</ApplicationTypeRevision> + <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="..\GraphicsEngineD3D11.Shared\GraphicsEngineD3D11.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj.filters b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj.filters new file mode 100644 index 00000000..4228787f --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj.filters @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj new file mode 100644 index 00000000..37889180 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{581c72cf-7f31-4eba-8f6e-743ca5774742}</ProjectGuid> + <RootNamespace>GraphicsEngineD3D11</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <AppContainerApplication>true</AppContainerApplication> + <ApplicationType>Windows Phone</ApplicationType> + <ApplicationTypeRevision>8.1</ApplicationTypeRevision> + <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="..\GraphicsEngineD3D11.Shared\GraphicsEngineD3D11.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj.filters b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj.filters new file mode 100644 index 00000000..4228787f --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj.filters @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/include/BlendStateD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/BlendStateD3D11Impl.h new file mode 100644 index 00000000..9bfc8af2 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/BlendStateD3D11Impl.h @@ -0,0 +1,55 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::BlendStateD3D11Impl class + +#include "BlendStateD3D11.h" +#include "RenderDeviceD3D11.h" +#include "BlendStateBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IBlendStateD3D11 interface +class BlendStateD3D11Impl : public BlendStateBase<IBlendStateD3D11, IRenderDeviceD3D11> +{ +public: + typedef BlendStateBase<IBlendStateD3D11, IRenderDeviceD3D11 > TBlendStateBase; + + BlendStateD3D11Impl(class RenderDeviceD3D11Impl *pDeviceD3D11, const BlendStateDesc& BuffDesc); + ~BlendStateD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + /// Implementation of the IBlendStateD3D11::GetD3D11BlendState() method. + ID3D11BlendState *GetD3D11BlendState(){ return m_pd3d11BlendState; } + +private: + /// D3D11 Blend state object + Diligent::CComPtr<ID3D11BlendState> m_pd3d11BlendState; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h new file mode 100644 index 00000000..190599cd --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h @@ -0,0 +1,63 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::BufferD3D11Impl class + +#include "BufferD3D11.h" +#include "RenderDeviceD3D11.h" +#include "BufferBase.h" +#include "BufferViewD3D11Impl.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IBufferD3D11 interface +class BufferD3D11Impl : public BufferBase<IBufferD3D11, BufferViewD3D11Impl> +{ +public: + typedef BufferBase<IBufferD3D11, BufferViewD3D11Impl> TBufferBase; + BufferD3D11Impl(class RenderDeviceD3D11Impl *pDeviceD3D11, const BufferDesc& BuffDesc, const BufferData &BuffData = BufferData()); + ~BufferD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData )override; + virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size )override; + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; + virtual void Unmap( IDeviceContext *pContext )override; + virtual ID3D11Buffer *GetD3D11Buffer()override{ return m_pd3d11Buffer; } + +private: + virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, IBufferView **ppView, bool bIsDefaultView )override; + + void CreateUAV( struct BufferViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ); + void CreateSRV( struct BufferViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ); + + friend class DeviceContextD3D11Impl; + Diligent::CComPtr<ID3D11Buffer> m_pd3d11Buffer; ///< D3D11 buffer object +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.h new file mode 100644 index 00000000..37308ae9 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.h @@ -0,0 +1,56 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::BufferViewD3D11Impl class + +#include "BufferViewD3D11.h" +#include "RenderDeviceD3D11.h" +#include "BufferViewBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IBufferViewD3D11 interface +class BufferViewD3D11Impl : public BufferViewBase<IBufferViewD3D11> +{ +public: + typedef BufferViewBase<IBufferViewD3D11> TBufferViewBase; + + BufferViewD3D11Impl( IRenderDevice *pDevice, + const BufferViewDesc& ViewDesc, + class IBuffer *pBuffer, + ID3D11View* pD3D11View, + bool bIsDefaultView); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual ID3D11View* GetD3D11View(); + +protected: + Diligent::CComPtr<ID3D11View> m_pD3D11View; ///<D3D11 view +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/D3D11DebugUtilities.h b/Graphics/GraphicsEngineD3D11/include/D3D11DebugUtilities.h new file mode 100644 index 00000000..1becfb17 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/D3D11DebugUtilities.h @@ -0,0 +1,57 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Debug utilities + +#include "DeviceObject.h" +#include "ShaderD3D11Impl.h" + +#ifdef _DEBUG +# define VERIFY_RESOURCE_ARRAYS +#endif + +namespace Diligent +{ +#ifdef VERIFY_RESOURCE_ARRAYS + + /// Debug function that verifies that cached engine objects and d3d11 shader resource views in two provided arrays are consistent + void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundSRV > &SRVs, const std::vector<ID3D11ShaderResourceView*> d3d11SRVs, IShader *pShader ); + + /// Debug function that verifies that cached engine objects and d3d11 unordered access views in two provided arrays are consistent + void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundUAV > &UAVs, const std::vector<ID3D11UnorderedAccessView*> d3d11UAVs, IShader *pShader ); + + /// Debug function that verifies that cached engine objects and d3d11 constant buffers in two provided arrays are consistent + void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundCB > &CBs, const std::vector<ID3D11Buffer*> d3d11CBs, IShader *pShader ); + + /// Debug function that verifies that cached engine objects and d3d11 samplers in two provided arrays are consistent + void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundSampler >&Samplers, const std::vector<ID3D11SamplerState*> d3d11Samplers, IShader *pShader ); + +#else + + #define dbgVerifyResourceArrays(...) + +#endif +} diff --git a/Graphics/GraphicsEngineD3D11/include/D3D11TypeConversions.h b/Graphics/GraphicsEngineD3D11/include/D3D11TypeConversions.h new file mode 100644 index 00000000..ddc76591 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/D3D11TypeConversions.h @@ -0,0 +1,147 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Type conversion routines + +#include "GraphicsTypes.h" + +namespace Diligent +{ + +inline UINT BindFlagsToD3D11BindFlags(Uint32 BindFlags) +{ + UINT D3D11BindFlags = 0; + D3D11BindFlags = D3D11BindFlags | ((BindFlags & BIND_VERTEX_BUFFER) ? D3D11_BIND_VERTEX_BUFFER : 0); + D3D11BindFlags = D3D11BindFlags | ((BindFlags & BIND_INDEX_BUFFER) ? D3D11_BIND_INDEX_BUFFER : 0); + D3D11BindFlags = D3D11BindFlags | ((BindFlags & BIND_UNIFORM_BUFFER) ? D3D11_BIND_CONSTANT_BUFFER : 0); + D3D11BindFlags = D3D11BindFlags | ((BindFlags & BIND_SHADER_RESOURCE) ? D3D11_BIND_SHADER_RESOURCE : 0); + D3D11BindFlags = D3D11BindFlags | ((BindFlags & BIND_STREAM_OUTPUT) ? D3D11_BIND_STREAM_OUTPUT : 0); + D3D11BindFlags = D3D11BindFlags | ((BindFlags & BIND_RENDER_TARGET) ? D3D11_BIND_RENDER_TARGET : 0); + D3D11BindFlags = D3D11BindFlags | ((BindFlags & BIND_DEPTH_STENCIL) ? D3D11_BIND_DEPTH_STENCIL : 0); + D3D11BindFlags = D3D11BindFlags | ((BindFlags & BIND_UNORDERED_ACCESS) ? D3D11_BIND_UNORDERED_ACCESS : 0); + return D3D11BindFlags; +} + +inline D3D11_PRIMITIVE_TOPOLOGY TopologyToDX11Topology(PRIMITIVE_TOPOLOGY Topology) +{ + switch( Topology ) + { + case PRIMITIVE_TOPOLOGY_UNDEFINED: return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + case PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + case PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + case PRIMITIVE_TOPOLOGY_POINT_LIST: return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + case PRIMITIVE_TOPOLOGY_LINE_LIST: return D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + default: UNEXPECTED("Unsupported primitive topology" ); return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + } +} + +DXGI_FORMAT TypeToDXGI_Format(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized); + +DXGI_FORMAT TexFormatToDXGI_Format(TEXTURE_FORMAT TexFormat, Uint32 BindFlags = 0); + +inline D3D11_USAGE UsageToD3D11Usage(USAGE Usage) +{ + switch(Usage) + { + case USAGE_STATIC: return D3D11_USAGE_IMMUTABLE; + case USAGE_DEFAULT: return D3D11_USAGE_DEFAULT; + case USAGE_DYNAMIC: return D3D11_USAGE_DYNAMIC; + case USAGE_CPU_ACCESSIBLE: return D3D11_USAGE_STAGING; + default: UNEXPECTED("Unknow usage" ); return D3D11_USAGE_DEFAULT; + } +} + +inline D3D11_MAP MapTypeToD3D11MapType(MAP_TYPE MapType) +{ + switch(MapType) + { + case MAP_READ: return D3D11_MAP_READ; + case MAP_WRITE: return D3D11_MAP_WRITE; + case MAP_READ_WRITE: return D3D11_MAP_READ_WRITE; + case MAP_WRITE_DISCARD: return D3D11_MAP_WRITE_DISCARD; + case MAP_WRITE_NO_OVERWRITE:return D3D11_MAP_WRITE_NO_OVERWRITE; + default: UNEXPECTED( "Unknown map type" ); return D3D11_MAP_READ; + } +} + +inline UINT MapFlagsToD3D11MapFlags(Uint32 MapFlags) +{ + UINT D3D11MapFlags = 0; + D3D11MapFlags |= (MapFlags & MAP_FLAG_DO_NOT_WAIT) ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0; + return D3D11MapFlags; +} + +inline UINT CPUAccessFlagsToD3D11CPUAccessFlags(Uint32 Flags) +{ + UINT D3D11CPUAccessFlags = 0; + D3D11CPUAccessFlags |= (Flags & CPU_ACCESS_READ) ? D3D11_CPU_ACCESS_READ : 0; + D3D11CPUAccessFlags |= (Flags & CPU_ACCESS_WRITE) ? D3D11_CPU_ACCESS_WRITE : 0; + return D3D11CPUAccessFlags; +} + +inline UINT MiscTextureFlagsToD3D11Flags(Uint32 Flags) +{ + UINT D3D11MiscFlags = 0; + D3D11MiscFlags |= (Flags & MISC_TEXTURE_FLAG_GENERATE_MIPS) ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0; + return D3D11MiscFlags; +} + +D3D11_FILTER FilterTypeToD3D11Filter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter); + +inline D3D11_TEXTURE_ADDRESS_MODE TexAddressModeToD3D11AddressMode(TEXTURE_ADDRESS_MODE Mode) +{ + switch(Mode) + { + case TEXTURE_ADDRESS_UNKNOWN: UNEXPECTED("Texture address mode is not specified" ); return D3D11_TEXTURE_ADDRESS_CLAMP; + case TEXTURE_ADDRESS_WRAP: return D3D11_TEXTURE_ADDRESS_WRAP; + case TEXTURE_ADDRESS_MIRROR: return D3D11_TEXTURE_ADDRESS_MIRROR; + case TEXTURE_ADDRESS_CLAMP: return D3D11_TEXTURE_ADDRESS_CLAMP; + case TEXTURE_ADDRESS_BORDER: return D3D11_TEXTURE_ADDRESS_BORDER; + case TEXTURE_ADDRESS_MIRROR_ONCE: return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; + default: UNEXPECTED("Unknown texture address mode" ); return D3D11_TEXTURE_ADDRESS_CLAMP; + } +} + +inline D3D11_COMPARISON_FUNC ComparisonFuncToD3D11ComparisonFunc(COMPARISON_FUNCTION Func) +{ + switch(Func) + { + case COMPARISON_FUNC_UNKNOW: UNEXPECTED("Comparison function is not specified" ); return D3D11_COMPARISON_ALWAYS; + case COMPARISON_FUNC_NEVER: return D3D11_COMPARISON_NEVER; + case COMPARISON_FUNC_LESS: return D3D11_COMPARISON_LESS; + case COMPARISON_FUNC_EQUAL: return D3D11_COMPARISON_EQUAL; + case COMPARISON_FUNC_LESS_EQUAL: return D3D11_COMPARISON_LESS_EQUAL; + case COMPARISON_FUNC_GREATER: return D3D11_COMPARISON_GREATER; + case COMPARISON_FUNC_NOT_EQUAL: return D3D11_COMPARISON_NOT_EQUAL; + case COMPARISON_FUNC_GREATER_EQUAL: return D3D11_COMPARISON_GREATER_EQUAL; + case COMPARISON_FUNC_ALWAYS: return D3D11_COMPARISON_ALWAYS; + default: UNEXPECTED("Unknown comparison function" ); return D3D11_COMPARISON_ALWAYS; + } +} + +D3D11_STENCIL_OP StencilOpToD3D11StencilOp( STENCIL_OP ); + +} diff --git a/Graphics/GraphicsEngineD3D11/include/D3DErrors.h b/Graphics/GraphicsEngineD3D11/include/D3DErrors.h new file mode 100644 index 00000000..00029230 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/D3DErrors.h @@ -0,0 +1,89 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "Errors.h" + +/// \file +/// Declaration of Diligent::ComErrorDesc class + +namespace Diligent +{ + +/// Helper class that provides description of a COM error +class ComErrorDesc +{ +public: + ComErrorDesc( HRESULT hr ) + { + FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + hr, + MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), + m_Msg, + _countof(m_Msg), + NULL ); + auto nLen = strlen( m_Msg ); + if( nLen > 1 && m_Msg[nLen - 1] == '\n' ) + { + m_Msg[nLen - 1] = 0; + if( m_Msg[nLen - 2] == '\r' ) + { + m_Msg[nLen - 2] = 0; + } + } + } + + const char* Get(){ return m_Msg; } + +private: + char m_Msg[4096]; +}; + +} + + +#define CHECK_D3D_RESULT_THROW(Expr, Message)\ +{ \ + HRESULT _hr_ = Expr; \ + if(FAILED(_hr_)) \ + { \ + ComErrorDesc ErrDesc( _hr_ ); \ + LOG_ERROR_AND_THROW( Message, "\nHRESULT Desc: ", ErrDesc.Get());\ + } \ +} + +#define CHECK_D3D_RESULT_THROW_EX(Expr, ...)\ +{ \ + HRESULT _hr_ = Expr; \ + if(FAILED(_hr_)) \ + { \ + Diligent::MsgStream ms; \ + Diligent::FormatMsg(ms, __VA_ARGS__); \ + ComErrorDesc ErrDesc( _hr_ ); \ + LOG_ERROR_AND_THROW( ms.str(), "\nHRESULT Desc: ", ErrDesc.Get());\ + } \ +} diff --git a/Graphics/GraphicsEngineD3D11/include/DSStateD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DSStateD3D11Impl.h new file mode 100644 index 00000000..55aaa2ce --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/DSStateD3D11Impl.h @@ -0,0 +1,54 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::DSStateD3D11Impl class + +#include "DepthStencilStateD3D11.h" +#include "RenderDeviceD3D11.h" +#include "DepthStencilStateBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IDepthStencilStateD3D11 interface +class DSStateD3D11Impl : public DepthStencilStateBase<IDepthStencilStateD3D11, IRenderDeviceD3D11 > +{ +public: + typedef DepthStencilStateBase<IDepthStencilStateD3D11, IRenderDeviceD3D11 > TDepthStencilStateBase; + + DSStateD3D11Impl(class RenderDeviceD3D11Impl *pDeviceD3D11, const DepthStencilStateDesc& BuffDesc); + ~DSStateD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + ID3D11DepthStencilState *GetD3D11DepthStencilState(){ return m_pd3d11DepthStencilState; } + +private: + /// D3D11 depth-stencil state + Diligent::CComPtr<ID3D11DepthStencilState> m_pd3d11DepthStencilState; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h new file mode 100644 index 00000000..a4102db6 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h @@ -0,0 +1,260 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::DeviceContextD3D11Impl class + +#include "DeviceContextD3D11.h" +#include "DeviceContextBase.h" +#include "ShaderD3D11Impl.h" + +#ifdef _DEBUG +# define VERIFY_CONTEXT_BINDINGS +#endif + +namespace Diligent +{ + +/// Implementation of the Diligent::IDeviceContextD3D11 interface +class DeviceContextD3D11Impl : public DeviceContextBase<IDeviceContextD3D11> +{ +public: + typedef DeviceContextBase<IDeviceContextD3D11> TDeviceContextBase; + + DeviceContextD3D11Impl(IRenderDevice *pDevice, ID3D11DeviceContext *pd3d11DeviceContext); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void SetShaders( IShader **ppShaders, Uint32 NumShadersToSet )override; + + virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override; + + virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )override; + virtual void ClearState()override; + + virtual void SetVertexDescription( IVertexDescription *pVertexDesc )override; + + virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset )override; + + virtual void SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef = 0 )override; + + virtual void SetRasterizerState( IRasterizerState *pRS )override; + + virtual void SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask )override; + + virtual void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight )override; + + virtual void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight )override; + + virtual void SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil )override; + + virtual void Draw( DrawAttribs &DrawAttribs )override; + + virtual void DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )override; + + virtual void ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil)override; + + virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA )override; + + virtual void Flush()override; + + ID3D11DeviceContext* GetD3D11DeviceContext(){ return m_pd3d11DeviceContext; } + + void RebindRenderTargets(); + + /// Clears the state caches. This function is called once per frame + /// (before present) to release all outstanding objects + /// that are only kept alive by references in the cache + void ClearShaderStateCache(); + + /// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute) + static const int NumShaderTypes = 6; + +private: + + /// Goes through the list of bound shaders and binds all required + /// d3d11 resource to the d3d11 device context, for each shader. + void SetD3DShadersAndResources(); + + /// Binds d3d11 index buffer to the d3d11 device context. + void SetD3DIndexBuffer(VALUE_TYPE IndexType); + + /// Binds d3d11 vertex buffers to the d3d11 device context. + void SetD3DVertexBuffers(); + + /// Binds d3d11 constant buffers to the d3d11 device context + void SetD3DConstantBuffers ( class ShaderD3D11Impl *pShader ); + /// Binds d3d11 shader resource views to the d3d11 device context + void SetD3DSRVs ( class ShaderD3D11Impl *pShader ); + /// Binds d3d11 unordered access views to the d3d11 device context + void SetD3DUAVs ( class ShaderD3D11Impl *pShader ); + /// Binds d3d11 samplers to the d3d11 device context + void SetD3DSamplers ( class ShaderD3D11Impl *pShader ); + + /// Helper template function used to facilitate resource unbinding + template<typename TBoundResourceType, + typename TD3D11ResourceType, + typename TSetD3D11View> + void UnbindResourceView(std::vector<TBoundResourceType> BoundResourcesArr[], + std::vector<TD3D11ResourceType> BoundD3D11ResourcesArr[], + IDeviceObject *pResToUnbind, + TSetD3D11View SetD3D11ViewMethods[]); + + /// Unbinds a texture from the shader resource view slots. + /// \note The function only unbinds the texture from d3d11 device + /// context. All shader bindings are retained. + void UnbindTextureFromInput(ITexture *pTexture); + + /// Unbinds a buffer from the input (shader resource views slots, index + /// and vertex buffer slots). + /// \note The function only unbinds the buffer from d3d11 device + /// context. All shader bindings are retained. + void UnbindBufferFromInput(IBuffer *pBuffer); + + /// Unbinds a resource from the UAV slots. + /// \note The function only unbinds the texture from the device + /// context. All shader bindings are retained. + void UnbindResourceFromUAV(IDeviceObject *pResource); + + /// Unbinds a texture from render target slots. + void UnbindTextureFromRenderTarget(IDeviceObject *pResource); + + /// Unbinds a texture from depth-stencil. + void UnbindTextureFromDepthStencil(IDeviceObject *pResource); + + /// Helper template function that facilitates shader binding + /// \tparam TD3D11ShaderType - Type of D3D11 shader being set (ID3D11PixelShader, ID3D11VertexShader, etc.) + /// \tparam TBindShaderMethdType - Type of the d3d11 device context mehtod that sets the shader + /// (ID3D11DeviceContext::VSSetShader, ID3D11DeviceContext::PSSetShader, etc.) + /// \param BoundShaderFlags - Flags indicating which shader stages are currently active + /// \param NewShaders - Array of pointers to the new shaders to be bound + /// \param ShaderType - Type of the shader being bound + /// \param BindShaderMethod - Pointer to the d3d11 device context mehtod that sets the shader + /// (ID3D11DeviceContext::VSSetShader, ID3D11DeviceContext::PSSetShader, etc.) + template<typename TD3D11ShaderType, typename TBindShaderMethdType> + void SetD3D11ShaderHelper(Uint32 BoundShaderFlags, + ShaderD3D11Impl* NewShaders[], + SHADER_TYPE ShaderType, + TBindShaderMethdType BindShaderMethod); + + Diligent::CComPtr<ID3D11DeviceContext> m_pd3d11DeviceContext; ///< D3D11 device context + DrawAttribs m_LastDrawAttribs; + + /// An array of D3D11 constant buffers currently bound to the D3D11 device context, + /// for each shader type. + std::vector<ID3D11Buffer*> m_BoundD3D11CBs [NumShaderTypes]; + /// An array of D3D11 shader resource views currently bound to the D3D11 device context, + /// for each shader type. + std::vector<ID3D11ShaderResourceView*> m_BoundD3D11SRVs [NumShaderTypes]; + /// An array of D3D11 samplers currently bound to the D3D11 device context, + /// for each shader type. + std::vector<ID3D11SamplerState*> m_BoundD3D11Samplers[NumShaderTypes]; + /// An array of D3D11 UAVs currently bound to the D3D11 device context, + /// for each shader type. + std::vector<ID3D11UnorderedAccessView*> m_BoundD3D11UAVs [NumShaderTypes]; + + /// An array of strong references to resources associated with the bound + /// constant buffers, for each shader type. + std::vector<ShaderD3D11Impl::BoundCB> m_BoundCBs[NumShaderTypes]; + /// An array of strong references to resources associated with the + /// bound SRV, for each shader type. + std::vector<ShaderD3D11Impl::BoundSRV> m_BoundSRVs[NumShaderTypes]; + /// An array of strong references to resources associated with the + /// bound samplers, for each shader type. + std::vector<ShaderD3D11Impl::BoundSampler> m_BoundSamplers[NumShaderTypes]; + /// An array of strong references to resources associated with the + /// bound UAVs, for each shader type. + std::vector<ShaderD3D11Impl::BoundUAV> m_BoundUAVs[NumShaderTypes]; + + /// An array of D3D11 vertex buffers currently bound to the D3D device context + std::vector< Diligent::CComPtr<ID3D11Buffer> > m_BoundD3D11VertexBuffers; + /// An array of strides of currently bound vertex buffers + std::vector< UINT > m_BoundD3D11VBStrides; + /// An array of offsets of currently bound vertex buffers + std::vector< UINT > m_BoundD3D11VBOffsets; + + /// Strong reference to the D3D11 buffer currently bound as index buffer + /// to the D3D device context + Diligent::CComPtr<ID3D11Buffer> m_BoundD3D11IndexBuffer; + /// Format of currently bound D3D11 index buffer + DXGI_FORMAT m_BoundD3D11IndexFmt; + /// Offset of currently bound D3D11 index buffer + Uint32 m_BoundD3D11IndexDataStartOffset; + + /// Strong references to the currently bound D3D11 shaders + Diligent::CComPtr<ID3D11DeviceChild> m_BoundD3DShaders[NumShaderTypes]; + +#ifdef VERIFY_CONTEXT_BINDINGS + /// Helper template function used to facilitate context verification + template<UINT MaxResources, typename TD3D11ResourceType, typename TGetD3D11ResourcesType> + void dbgVerifyContextResources(std::vector<TD3D11ResourceType> BoundD3D11ResourcesArr[], + TGetD3D11ResourcesType GetD3D11ResMethods[], + const Char *ResourceName, + SHADER_TYPE ShaderType); + + /// Debug function that verifies that SRVs cached in m_BoundD3D11SRVs + /// array comply with resources actually bound to the D3D11 device context + void dbgVerifyContextSRVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + + /// Debug function that verifies that UAVs cached in m_BoundD3D11UAVs + /// array comply with resources actually bound to the D3D11 device context + void dbgVerifyContextUAVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + + /// Debug function that verifies that samplers cached in m_BoundD3D11Samplers + /// array comply with resources actually bound to the D3D11 device context + void dbgVerifyContextSamplers(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + + /// Debug function that verifies that constant buffers cached in m_BoundD3D11CBs + /// array comply with buffers actually bound to the D3D11 device context + void dbgVerifyContextCBs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + + /// Debug function that verifies that the index buffer cached in + /// m_BoundD3D11IndexBuffer is the buffer actually bound to the D3D11 + /// device context + void dbgVerifyIndexBuffer(); + + /// Debug function that verifies that vertex buffers cached in + /// m_BoundD3D11VertexBuffers are the buffers actually bound to the D3D11 + /// device context + void dbgVerifyVertexBuffers(); + + /// Debug function that verifies that shaders cached in + /// m_BoundD3DShaders are the shaders actually bound to the D3D11 + /// device context + void dbgVerifyShaders(); + +#else + + #define dbgVerifyContextSRVs(...) + #define dbgVerifyContextUAVs(...) + #define dbgVerifyContextSamplers(...) + #define dbgVerifyContextCBs(...) + #define dbgVerifyIndexBuffer(...) + #define dbgVerifyVertexBuffers(...) + #define dbgVerifyShaders(...) + +#endif +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions.fxh b/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions.fxh new file mode 100644 index 00000000..fd19be08 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions.fxh @@ -0,0 +1,61 @@ +#ifndef _HLSL_DEFINITIONS_ +#define _HLSL_DEFINITIONS_ + +#define HLSL + +#define NDC_MIN_Z 0.0 // Minimal z in the normalized device space + +#define F3NDC_XYZ_TO_UVD_SCALE float3(0.5, -0.5, 1.0) + +float2 NormalizedDeviceXYToTexUV( float2 f2ProjSpaceXY ) +{ + return float2(0.5,0.5) + float2(0.5,-0.5) * f2ProjSpaceXY.xy; +} + +float NormalizedDeviceZToDepth(float fNDC_Z) +{ + return fNDC_Z; +} + +float DepthToNormalizedDeviceZ(float fDepth) +{ + return fDepth; +} + +// Relational and logical operators +#define Less(x,y) ((x)<(y)) +#define LessEqual(x,y) ((x)<=(y)) +#define Greater(x,y) ((x)>(y)) +#define GreaterEqual(x,y) ((x)>=(y)) +#define Equal(x,y) ((x)==(y)) +#define NotEqual(x,y) ((x)!=(y)) +#define Not(x) (!(x)) +#define And(x,y) ((x)&&(y)) +#define Or(x,y) ((x)||(y)) + +float4 BoolToFloat( bool4 b4 ) +{ + return float4(b4.x ? 1.0 : 0.0, + b4.y ? 1.0 : 0.0, + b4.z ? 1.0 : 0.0, + b4.w ? 1.0 : 0.0); +} +float3 BoolToFloat( bool3 b3 ) +{ + return float3(b3.x ? 1.0 : 0.0, + b3.y ? 1.0 : 0.0, + b3.z ? 1.0 : 0.0); +} +float2 BoolToFloat( bool2 b2 ) +{ + return float2(b2.x ? 1.0 : 0.0, + b2.y ? 1.0 : 0.0); +} +float BoolToFloat( bool b ) +{ + return b.x ? 1.0 : 0.0; +} + +#define MATRIX_ELEMENT(mat, row, col) mat[row][col] + +#endif // _HLSL_DEFINITIONS_ diff --git a/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions_inc.fxh b/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions_inc.fxh new file mode 100644 index 00000000..84012ff1 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions_inc.fxh @@ -0,0 +1,61 @@ +"#ifndef _HLSL_DEFINITIONS_\n" +"#define _HLSL_DEFINITIONS_\n" +"\n" +"#define HLSL\n" +"\n" +"#define NDC_MIN_Z 0.0 // Minimal z in the normalized device space\n" +"\n" +"#define F3NDC_XYZ_TO_UVD_SCALE float3(0.5, -0.5, 1.0)\n" +"\n" +"float2 NormalizedDeviceXYToTexUV( float2 f2ProjSpaceXY )\n" +"{\n" +" return float2(0.5,0.5) + float2(0.5,-0.5) * f2ProjSpaceXY.xy;\n" +"}\n" +"\n" +"float NormalizedDeviceZToDepth(float fNDC_Z)\n" +"{\n" +" return fNDC_Z;\n" +"}\n" +"\n" +"float DepthToNormalizedDeviceZ(float fDepth)\n" +"{\n" +" return fDepth;\n" +"}\n" +"\n" +"// Relational and logical operators\n" +"#define Less(x,y) ((x)<(y))\n" +"#define LessEqual(x,y) ((x)<=(y))\n" +"#define Greater(x,y) ((x)>(y))\n" +"#define GreaterEqual(x,y) ((x)>=(y))\n" +"#define Equal(x,y) ((x)==(y))\n" +"#define NotEqual(x,y) ((x)!=(y))\n" +"#define Not(x) (!(x))\n" +"#define And(x,y) ((x)&&(y))\n" +"#define Or(x,y) ((x)||(y))\n" +"\n" +"float4 BoolToFloat( bool4 b4 )\n" +"{\n" +" return float4(b4.x ? 1.0 : 0.0,\n" +" b4.y ? 1.0 : 0.0,\n" +" b4.z ? 1.0 : 0.0,\n" +" b4.w ? 1.0 : 0.0);\n" +"}\n" +"float3 BoolToFloat( bool3 b3 )\n" +"{\n" +" return float3(b3.x ? 1.0 : 0.0,\n" +" b3.y ? 1.0 : 0.0,\n" +" b3.z ? 1.0 : 0.0);\n" +"}\n" +"float2 BoolToFloat( bool2 b2 )\n" +"{\n" +" return float2(b2.x ? 1.0 : 0.0,\n" +" b2.y ? 1.0 : 0.0);\n" +"}\n" +"float BoolToFloat( bool b )\n" +"{\n" +" return b.x ? 1.0 : 0.0;\n" +"}\n" +"\n" +"#define MATRIX_ELEMENT(mat, row, col) mat[row][col]\n" +"\n" +"#endif // _HLSL_DEFINITIONS_\n" diff --git a/Graphics/GraphicsEngineD3D11/include/RasterizerStateD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/RasterizerStateD3D11Impl.h new file mode 100644 index 00000000..aad6f2ad --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/RasterizerStateD3D11Impl.h @@ -0,0 +1,54 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RasterizerStateD3D11Impl class + +#include "RasterizerStateD3D11.h" +#include "RenderDeviceD3D11.h" +#include "RasterizerStateBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IRasterizerStateD3D11 interface +class RasterizerStateD3D11Impl : public RasterizerStateBase<IRasterizerStateD3D11, IRenderDeviceD3D11> +{ +public: + typedef RasterizerStateBase<IRasterizerStateD3D11, IRenderDeviceD3D11 > TRasterizerStateBase; + + RasterizerStateD3D11Impl(class RenderDeviceD3D11Impl *pDeviceD3D11, const RasterizerStateDesc& BuffDesc); + ~RasterizerStateD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + ID3D11RasterizerState *GetD3D11RasterizerState(){ return m_pd3d11RasterizerState; } + +private: + /// D3D11 rasterizer state + Diligent::CComPtr<ID3D11RasterizerState> m_pd3d11RasterizerState; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h new file mode 100644 index 00000000..0f374b5c --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h @@ -0,0 +1,73 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RenderDeviceD3D11Impl class + +#include "RenderDeviceD3D11.h" +#include "RenderDeviceBase.h" +#include "DeviceContextD3D11.h" + +/// Namespace for the Direct3D11 implementation of the graphics engine +namespace Diligent +{ + +/// Implementation of the Diligent::IRenderDeviceD3D11 interface +class RenderDeviceD3D11Impl : public RenderDeviceBase<IRenderDeviceD3D11> +{ +public: + typedef RenderDeviceBase<IRenderDeviceD3D11> TRenderDeviceBase; + + RenderDeviceD3D11Impl( ID3D11Device *pd3d11Device ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer); + + virtual void CreateVertexDescription( const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc ); + + virtual void CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader); + + virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture); + + virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler); + + virtual void CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState ); + + virtual void CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState ); + + virtual void CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState ); + + ID3D11Device* GetD3D11Device(){return m_pd3d11Device;} + +private: + virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat ); + + void FlagSupportedTexFormats(); + + /// D3D11 device + Diligent::CComPtr<ID3D11Device> m_pd3d11Device; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.h new file mode 100644 index 00000000..f48d645e --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.h @@ -0,0 +1,55 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::SamplerD3D11Impl class + +#include "SamplerD3D11.h" +#include "RenderDeviceD3D11.h" +#include "SamplerBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::ISamplerD3D11 interface +class SamplerD3D11Impl : public SamplerBase<ISamplerD3D11, IRenderDeviceD3D11> +{ +public: + typedef SamplerBase<ISamplerD3D11, IRenderDeviceD3D11> TSamplerBase; + + SamplerD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const SamplerDesc& SamplerDesc); + ~SamplerD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual ID3D11SamplerState* GetD3D11SamplerState(){ return m_pd3dSampler; } + +private: + friend class ShaderD3D11Impl; + /// D3D11 sampler + Diligent::CComPtr<ID3D11SamplerState> m_pd3dSampler; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h new file mode 100644 index 00000000..4066947e --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h @@ -0,0 +1,231 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderD3D11Impl class + +#include "ShaderD3D11.h" +#include "RenderDeviceD3D11.h" +#include "ShaderBase.h" + +#ifdef _DEBUG +# define VERIFY_SHADER_BINDINGS +#endif + +namespace Diligent +{ + +class ResourceMapping; + +/// Implementation of the Diligent::IShaderD3D11 interface +class ShaderD3D11Impl : public ShaderBase<IShaderD3D11, IRenderDeviceD3D11> +{ +public: + typedef ShaderBase<IShaderD3D11, IRenderDeviceD3D11> TShaderBase; + + ShaderD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const ShaderCreationAttribs &ShaderCreationAttribs); + ~ShaderD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags )override; + + virtual IShaderVariable* GetShaderVariable( const Char* Name )override; + + /// Describes resources associated with the bound constant buffer + struct BoundCB + { + /// Strong reference to the buffer + Diligent::RefCntAutoPtr<IDeviceObject> pBuff; + /// Strong referene to the D3D11 buffer interface + Diligent::CComPtr<ID3D11Buffer> pd3d11Buff; + }; + + /// Describes resources associated with the bound sampler + struct BoundSampler + { + /// Strong reference to the sampler + Diligent::RefCntAutoPtr<IDeviceObject> pSampler; + /// Strong referene to the D3D11 sampler state interface + Diligent::CComPtr<ID3D11SamplerState> pd3d11Sampler; + }; + + /// Describes resources associated with the bound SRV + struct BoundSRV + { + /// Strong reference to the resource bound as SRV + Diligent::RefCntAutoPtr<IDeviceObject> pResource; + /// Strong reference to the resource view + Diligent::RefCntAutoPtr<IDeviceObject> pView; + /// Strong referene to the D3D11 SRV interface + Diligent::CComPtr<ID3D11ShaderResourceView> pd3d11View; + }; + + /// Describes resources associated with the bound UAV + struct BoundUAV + { + /// Strong reference to the resource bound as UAV + Diligent::RefCntAutoPtr<IDeviceObject> pResource; + /// Strong reference to the resource view + Diligent::RefCntAutoPtr<IDeviceObject> pView; + /// Strong referene to the D3D11 UAV interface + Diligent::CComPtr<ID3D11UnorderedAccessView> pd3d11View; + }; + + /// Returns a const reference to the zero-slot-based array of bound constant buffers + const std::vector< BoundCB >& GetBoundCBs() { return m_BoundCBs; } + /// Returns a const reference to the zero-slot-based array of bound samplers + const std::vector< BoundSampler >& GetBoundSamplers() { return m_BoundSamplers; } + /// Returns a const reference to the zero-slot-based array bound SRVs + const std::vector< BoundSRV >& GetBoundSRVs() { return m_BoundSRVs; } + /// Returns a const reference to the zero-slot-based array bound UAVs + const std::vector< BoundUAV >& GetBoundUAVs() { return m_BoundUAVs; } + + virtual ID3D11DeviceChild* GetD3D11Shader()override{ return m_pShader; } + +#ifdef VERIFY_SHADER_BINDINGS + void dbgVerifyBindings(); +#endif + +private: + void BindConstantBuffers( IResourceMapping* pResourceMapping, Uint32 Flags ); + + void BindSRVsAndSamplers( IResourceMapping* pResourceMapping, Uint32 Flags ); + + void BindUAVs( IResourceMapping* pResourceMapping, Uint32 Flags ); + + static const String m_SamplerSuffix; + + struct D3D11ShaderVarBase : ShaderVariableBase + { + D3D11ShaderVarBase( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint ) : + ShaderVariableBase( pShader ), + Name(_Name), + BindPoint(_BindPoint) + {} + + String Name; + UINT BindPoint; + const String& GetName(){ return Name; } + }; + + struct ConstBuffBindInfo : D3D11ShaderVarBase + { + ConstBuffBindInfo( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint ) : + D3D11ShaderVarBase( pShader, _Name, _BindPoint ) + {} + virtual void Set(IDeviceObject *pObject)override; + bool IsBound(); + }; + + struct TexAndSamplerBindInfo : D3D11ShaderVarBase + { + TexAndSamplerBindInfo( ShaderD3D11Impl *pShader, const String& _TexName, UINT _TexBindPoint, const String &_SamplerName, UINT _SamplerBindPoint ) : + D3D11ShaderVarBase( pShader, _TexName, _TexBindPoint), + SamplerName(_SamplerName), + SamplerBindPoint(_SamplerBindPoint) + {} + + String SamplerName; + UINT SamplerBindPoint; + virtual void Set(IDeviceObject *pObject)override; + bool IsBound(); + }; + + struct UAVBindInfoBase : public D3D11ShaderVarBase + { + UAVBindInfoBase( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint, D3D_SHADER_INPUT_TYPE _Type ) : + D3D11ShaderVarBase( pShader, _Name, _BindPoint), + Type(_Type) + {} + + bool IsBound(); + D3D_SHADER_INPUT_TYPE Type; + }; + + struct TexUAVBindInfo : UAVBindInfoBase + { + TexUAVBindInfo( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint, D3D_SHADER_INPUT_TYPE _Type ) : + UAVBindInfoBase( pShader, _Name, _BindPoint, _Type ) + {} + + virtual void Set(IDeviceObject *pObject)override; + }; + + struct BuffUAVBindInfo : UAVBindInfoBase + { + BuffUAVBindInfo( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint, D3D_SHADER_INPUT_TYPE _Type ) : + UAVBindInfoBase( pShader, _Name, _BindPoint, _Type ) + {} + + virtual void Set(IDeviceObject *pObject)override; + }; + + struct BuffSRVBindInfo : D3D11ShaderVarBase + { + BuffSRVBindInfo( ShaderD3D11Impl *pShader, const String &_Name, UINT _BindPoint ) : + D3D11ShaderVarBase( pShader, _Name, _BindPoint) + {} + + virtual void Set(IDeviceObject *pObject)override; + bool IsBound(); + }; + + void LoadShaderResources(); + + friend class VertexDescD3D11Impl; + friend class DeviceContextD3D11Impl; + /// D3D11 shader + Diligent::CComPtr<ID3D11DeviceChild> m_pShader; + Diligent::CComPtr<ID3DBlob> m_pShaderByteCode;// Only stored for Vertex Shader + + std::vector<ConstBuffBindInfo> m_ConstanBuffers; + std::vector<TexAndSamplerBindInfo> m_TexAndSamplers; + std::vector<TexUAVBindInfo> m_TexUAVs; + std::vector<BuffUAVBindInfo> m_BuffUAVs; + std::vector<BuffSRVBindInfo> m_BuffSRVs; + + + /// An array of bound constant buffers. The data always starts at + /// slot 0 even when no resource is actually bound to the slot. + std::vector<BoundCB> m_BoundCBs; + + /// An array of bound samplers. The data always starts at + /// slot 0 even when no sampler is actually bound to the slot. + std::vector<BoundSampler> m_BoundSamplers; + + /// An array of bound SRVs. The data always starts at + /// slot 0 even when no resource is actually bound to the slot. + std::vector<BoundSRV> m_BoundSRVs; + + /// An array of bound UAVs. The data always starts at + /// slot 0 even when no resource is actually bound to the slot. + std::vector<BoundUAV> m_BoundUAVs; + + /// Hash map to look up shader variables by name. + std::unordered_map<Diligent::HashMapStringKey, IShaderVariable* > m_VariableHash; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h new file mode 100644 index 00000000..32cef19f --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h @@ -0,0 +1,66 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::SwapChainD3D11Impl class + +#include "SwapChainD3D11.h" +#include "SwapChainBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::ISwapChainD3D11 interface +class SwapChainD3D11Impl : public SwapChainBase<ISwapChainD3D11> +{ +public: + typedef SwapChainBase<ISwapChainD3D11> TSwapChainBase; + SwapChainD3D11Impl(const SwapChainDesc& SwapChainDesc, + class RenderDeviceD3D11Impl* pRenderDeviceD3D11, + class DeviceContextD3D11Impl* pDeviceContextD3D11, + void* pNativeWndHandle); + ~SwapChainD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual void Present(); + virtual void Resize( Uint32 NewWidth, Uint32 NewHeight ); + + virtual IDXGISwapChain *GetDXGISwapChain(){ return m_pSwapChain; } + + ID3D11RenderTargetView* GetRTV(){ return m_pRenderTargetView; } + ID3D11DepthStencilView* GetDSV(){ return m_pDepthStencilView; } + +private: + void CreateRTVandDSV(); + /// D3D11 swap chain + Diligent::CComPtr<IDXGISwapChain> m_pSwapChain; + /// Back buffer render target view + Diligent::CComPtr<ID3D11RenderTargetView> m_pRenderTargetView; + /// Back buffer depth-stencil view + Diligent::CComPtr<ID3D11DepthStencilView> m_pDepthStencilView; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/Texture1D_D3D11.h b/Graphics/GraphicsEngineD3D11/include/Texture1D_D3D11.h new file mode 100644 index 00000000..e1cdcb2f --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/Texture1D_D3D11.h @@ -0,0 +1,47 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::Texture1D_D3D11 class + +#include "TextureBaseD3D11.h" + +namespace Diligent +{ + +class Texture1D_D3D11 : public TextureBaseD3D11 +{ +public: + Texture1D_D3D11(class RenderDeviceD3D11Impl *pDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData = TextureData()); + ~Texture1D_D3D11(); + +protected: + virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ); + virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ); + virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ); + virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ); +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/Texture2D_D3D11.h b/Graphics/GraphicsEngineD3D11/include/Texture2D_D3D11.h new file mode 100644 index 00000000..e098bce1 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/Texture2D_D3D11.h @@ -0,0 +1,47 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::Texture2D_D3D11 class + +#include "TextureBaseD3D11.h" + +namespace Diligent +{ + +class Texture2D_D3D11 : public TextureBaseD3D11 +{ +public: + Texture2D_D3D11(class RenderDeviceD3D11Impl *pDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData = TextureData()); + ~Texture2D_D3D11(); + +protected: + virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ); + virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ); + virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ); + virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ); +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/Texture3D_D3D11.h b/Graphics/GraphicsEngineD3D11/include/Texture3D_D3D11.h new file mode 100644 index 00000000..d5e11c8a --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/Texture3D_D3D11.h @@ -0,0 +1,47 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::Texture3D_D3D11 class + +#include "TextureBaseD3D11.h" + +namespace Diligent +{ + +class Texture3D_D3D11 : public TextureBaseD3D11 +{ +public: + Texture3D_D3D11(class RenderDeviceD3D11Impl *pDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData = TextureData()); + ~Texture3D_D3D11(); + +protected: + virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ); + virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ); + virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ); + virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ); +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h new file mode 100644 index 00000000..e787f238 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h @@ -0,0 +1,81 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::TextureBaseD3D11 class + +#include "TextureD3D11.h" +#include "RenderDeviceD3D11.h" +#include "TextureBase.h" +#include "TextureViewD3D11Impl.h" + +namespace Diligent +{ + +/// Base implementation of the Diligent::ITextureD3D11 interface +class TextureBaseD3D11 : public TextureBase<ITextureD3D11, TextureViewD3D11Impl> +{ +public: + typedef TextureBase<ITextureD3D11, TextureViewD3D11Impl> TTextureBase; + + TextureBaseD3D11(class RenderDeviceD3D11Impl *pDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData = TextureData()); + ~TextureBaseD3D11(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override; + + //virtual void CopyData(CTexture *pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size); + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; + virtual void Unmap( IDeviceContext *pContext )override; + + virtual ID3D11Resource* GetD3D11Texture(){ return m_pd3d11Texture; } + + void CopyData(IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ); + +protected: + void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )override; + void PrepareD3D11InitData(const TextureData &InitData, Uint32 NumSubresources, std::vector<D3D11_SUBRESOURCE_DATA> &D3D11InitData); + + virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ) = 0; + virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ) = 0; + virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ) = 0; + virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ) = 0; + + friend class RenderDeviceD3D11Impl; + /// D3D11 texture + Diligent::CComPtr<ID3D11Resource> m_pd3d11Texture; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.h new file mode 100644 index 00000000..6e138b41 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.h @@ -0,0 +1,59 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::TextureViewD3D11Impl class + +#include "TextureViewD3D11.h" +#include "RenderDeviceD3D11.h" +#include "TextureViewBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::ITextureViewD3D11 interface +class TextureViewD3D11Impl : public TextureViewBase<ITextureViewD3D11> +{ +public: + typedef TextureViewBase<ITextureViewD3D11> TTextureViewBase; + + TextureViewD3D11Impl( IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + class ITexture *pTexture, + ID3D11View* pD3D11View, + bool bIsDefaultView); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual ID3D11View* GetD3D11View()override; + + void GenerateMips( IDeviceContext *pContext )override; + +protected: + /// D3D11 view + Diligent::CComPtr<ID3D11View> m_pD3D11View; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/VertexDescD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/VertexDescD3D11Impl.h new file mode 100644 index 00000000..84b9ea78 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/VertexDescD3D11Impl.h @@ -0,0 +1,55 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::VertexDescD3D11Impl class + +#include "VertexDescriptionD3D11.h" +#include "RenderDeviceD3D11.h" +#include "VertexDescriptionBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IVertexDescriptionD3D11 interface +class VertexDescD3D11Impl : public VertexDescriptionBase<IVertexDescriptionD3D11> +{ +public: + typedef VertexDescriptionBase<IVertexDescriptionD3D11> TVertexDescriptionBase; + + VertexDescD3D11Impl( class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const LayoutDesc &LayoutDesc, IShader *pVertexShader ); + ~VertexDescD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual ID3D11InputLayout* GetD3D11InputLayout(){ return m_pd3d11InputLayout; } + +private: + friend class DeviceContextD3D11Impl; + /// D3D11 input layout + Diligent::CComPtr<ID3D11InputLayout> m_pd3d11InputLayout; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/pch.h b/Graphics/GraphicsEngineD3D11/include/pch.h new file mode 100644 index 00000000..d948fd48 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/pch.h @@ -0,0 +1,55 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define NOMINMAX + +#include "PlatformDefinitions.h" + +#include <vector> +#include <exception> +#include <algorithm> +#if defined(PLATFORM_WINDOWS) + #include <d3d11.h> +#elif defined(PLATFORM_WINDOWS_STORE) + #include <d3d11_2.h> +#endif + +#include "PlatformDefinitions.h" +#include "Errors.h" +#include "RefCntAutoPtr.h" +#include "DebugUtilities.h" +#include "D3DErrors.h" +#include "RenderDeviceBase.h" +#include "D3D11TypeConversions.h" +#include "ValidatedCast.h" +#include "ComPtr.h"
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/include/targetver.h b/Graphics/GraphicsEngineD3D11/include/targetver.h new file mode 100644 index 00000000..e76fe941 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/targetver.h @@ -0,0 +1,31 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include <SDKDDKVer.h> diff --git a/Graphics/GraphicsEngineD3D11/interface/BlendStateD3D11.h b/Graphics/GraphicsEngineD3D11/interface/BlendStateD3D11.h new file mode 100644 index 00000000..8fe1c302 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/BlendStateD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBlendStateD3D11 interface + +#include "BlendState.h" + +namespace Diligent +{ + +// {18FEA836-1DD6-4100-9C83-CEF71F8EC8F1} +static const Diligent::INTERFACE_ID IID_BlendStateD3D11 = +{ 0x18fea836, 0x1dd6, 0x4100, { 0x9c, 0x83, 0xce, 0xf7, 0x1f, 0x8e, 0xc8, 0xf1 } }; + +/// Interface to the blend state object implemented in D3D11 +class IBlendStateD3D11 : public Diligent::IBlendState +{ +public: + + /// Returns a pointer to the ID3D11BlendState interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11BlendState *GetD3D11BlendState() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/BufferD3D11.h b/Graphics/GraphicsEngineD3D11/interface/BufferD3D11.h new file mode 100644 index 00000000..46195298 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/BufferD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBufferD3D11 interface + +#include "Buffer.h" + +namespace Diligent +{ + +// {4A696D2E-44BB-4C4B-9DE2-3AF7C94DCFC0} +static const Diligent::INTERFACE_ID IID_BufferD3D11 = +{ 0x4a696d2e, 0x44bb, 0x4c4b, { 0x9d, 0xe2, 0x3a, 0xf7, 0xc9, 0x4d, 0xcf, 0xc0 } }; + +/// Interface to the buffer object implemented in D3D11 +class IBufferD3D11 : public Diligent::IBuffer +{ +public: + + /// Returns a pointer to the ID3D11Buffer interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11Buffer *GetD3D11Buffer() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/BufferViewD3D11.h b/Graphics/GraphicsEngineD3D11/interface/BufferViewD3D11.h new file mode 100644 index 00000000..32a75461 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/BufferViewD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBufferViewD3D11 interface + +#include "BufferView.h" + +namespace Diligent +{ + +// {6ABA95FC-CD7D-4C03-8CAE-AFC45F9696B7} +static const Diligent::INTERFACE_ID IID_BufferViewD3D11 = +{ 0x6aba95fc, 0xcd7d, 0x4c03, { 0x8c, 0xae, 0xaf, 0xc4, 0x5f, 0x96, 0x96, 0xb7 } }; + +/// Interface to the buffer view object implemented in D3D11 +class IBufferViewD3D11 : public Diligent::IBufferView +{ +public: + + /// Returns a pointer to the ID3D11View interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11View* GetD3D11View() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/DepthStencilStateD3D11.h b/Graphics/GraphicsEngineD3D11/interface/DepthStencilStateD3D11.h new file mode 100644 index 00000000..7e8bd567 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/DepthStencilStateD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IDepthStencilStateD3D11 interface + +#include "DepthStencilState.h" + +namespace Diligent +{ + +// {77EA665B-4D63-4D5F-AD8F-791FE79FC305} +static const Diligent::INTERFACE_ID IID_DepthStencilStateD3D11 = +{ 0x77ea665b, 0x4d63, 0x4d5f, { 0xad, 0x8f, 0x79, 0x1f, 0xe7, 0x9f, 0xc3, 0x5 } }; + +/// Interface to the depth stencil state object implemented in D3D11 +class IDepthStencilStateD3D11 : public Diligent::IDepthStencilState +{ +public: + + /// Returns a pointer to the ID3D11DepthStencilState interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11DepthStencilState *GetD3D11DepthStencilState() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/DeviceContextD3D11.h b/Graphics/GraphicsEngineD3D11/interface/DeviceContextD3D11.h new file mode 100644 index 00000000..972249b4 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/DeviceContextD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IDeviceContextD3D11 interface + +#include "DeviceContext.h" + +namespace Diligent +{ + +// {F0EE0335-C8AB-4EC1-BB15-B8EE5F003B99} +static const Diligent::INTERFACE_ID IID_DeviceContextD3D11 = +{ 0xf0ee0335, 0xc8ab, 0x4ec1, { 0xbb, 0x15, 0xb8, 0xee, 0x5f, 0x0, 0x3b, 0x99 } }; + +/// Interface to the device context object implemented in D3D11 +class IDeviceContextD3D11 : public Diligent::IDeviceContext +{ +public: + + /// Returns a pointer to the ID3D11DeviceContext interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11DeviceContext* GetD3D11DeviceContext() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/RasterizerStateD3D11.h b/Graphics/GraphicsEngineD3D11/interface/RasterizerStateD3D11.h new file mode 100644 index 00000000..7ebb7bf0 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/RasterizerStateD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRasterizerStateD3D11 interface + +#include "RasterizerState.h" + +namespace Diligent +{ + +// {10E96D54-1A17-4AB4-8A87-CD39211B348D} +static const Diligent::INTERFACE_ID IID_RasterizerStateD3D11 = +{ 0x10e96d54, 0x1a17, 0x4ab4, { 0x8a, 0x87, 0xcd, 0x39, 0x21, 0x1b, 0x34, 0x8d } }; + +/// Interface to the rasterizer state object implemented in D3D11 +class IRasterizerStateD3D11 : public Diligent::IRasterizerState +{ +public: + + /// Returns a pointer to the ID3D11RasterizerState interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11RasterizerState *GetD3D11RasterizerState() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/RenderDeviceD3D11.h b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceD3D11.h new file mode 100644 index 00000000..2baaa564 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRenderDeviceD3D11 interface + +#include "RenderDevice.h" + +namespace Diligent +{ + +// {05B1CBB8-FCAD-49EE-BADA-7801223EC3FE} +static const Diligent::INTERFACE_ID IID_RenderDeviceD3D11 = +{ 0x5b1cbb8, 0xfcad, 0x49ee, { 0xba, 0xda, 0x78, 0x1, 0x22, 0x3e, 0xc3, 0xfe } }; + +/// Interface to the render device object implemented in D3D11 +class IRenderDeviceD3D11 : public Diligent::IRenderDevice +{ +public: + + /// Returns a pointer to the ID3D11Device interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11Device* GetD3D11Device() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h new file mode 100644 index 00000000..d289fb65 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h @@ -0,0 +1,95 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "Errors.h" + +extern "C" +{ +#ifdef ENGINE_DLL + typedef void (*CreateDeviceAndImmediateContextD3D11Type)( + const Diligent::EngineCreationAttribs& CreationAttribs, + Diligent::IRenderDevice **ppDevice, + Diligent::IDeviceContext **ppContext ); + + typedef void (*CreateSwapChainD3D11Type)( + Diligent::IRenderDevice *pDevice, + Diligent::IDeviceContext *pImmediateContext, + const Diligent::SwapChainDesc& SwapChainDesc, + void* pNativeWndHandle, + Diligent::ISwapChain **ppSwapChain ); + + static void LoadGraphicsEngineD3D11(CreateDeviceAndImmediateContextD3D11Type &CreateDeviceFunc, CreateSwapChainD3D11Type &CreateSwapChainFunc) + { + CreateDeviceFunc = nullptr; + CreateSwapChainFunc = nullptr; + std::string LibName = "GraphicsEngineD3D11_"; + +#if _WIN64 + LibName += "64"; +#else + LibName += "32"; +#endif + +#ifdef _DEBUG + LibName += "d"; +#else + LibName += "r"; +#endif + + LibName += ".dll"; + auto hModule = LoadLibraryA( LibName.c_str() ); + if( hModule == NULL ) + { + LOG_ERROR_MESSAGE( "Failed to load ", LibName, " library." ); + return; + } + + CreateDeviceFunc = reinterpret_cast<CreateDeviceAndImmediateContextD3D11Type>( GetProcAddress(hModule, "CreateDeviceAndImmediateContextD3D11") ); + if( CreateDeviceFunc == NULL ) + { + LOG_ERROR_MESSAGE( "Failed to load CreateDeviceAndImmediateContextD3D11() from ", LibName, " library." ); + FreeLibrary( hModule ); + return; + } + + CreateSwapChainFunc = reinterpret_cast<CreateSwapChainD3D11Type>( GetProcAddress(hModule, "CreateSwapChainD3D11") ); + if( CreateSwapChainFunc == NULL ) + { + LOG_ERROR_MESSAGE( "Failed to load CreateSwapChainD3D11() from ", LibName, " library." ); + FreeLibrary( hModule ); + return; + } + } +#else + void CreateDeviceAndImmediateContextD3D11( const Diligent::EngineCreationAttribs& CreationAttribs, + Diligent::IRenderDevice **ppDevice, + Diligent::IDeviceContext **ppContext ); + void CreateSwapChainD3D11( Diligent::IRenderDevice *pDevice, + Diligent::IDeviceContext *pImmediateContext, + const Diligent::SwapChainDesc& SwapChainDesc, + void* pNativeWndHandle, + Diligent::ISwapChain **ppSwapChain ); +#endif +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/interface/SamplerD3D11.h b/Graphics/GraphicsEngineD3D11/interface/SamplerD3D11.h new file mode 100644 index 00000000..4266f89b --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/SamplerD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ISamplerD3D11 interface + +#include "Sampler.h" + +namespace Diligent +{ + +// {31A3BFAF-738E-4D8C-AD18-B021C5D948DD} +static const Diligent::INTERFACE_ID IID_SamplerD3D11 = +{ 0x31a3bfaf, 0x738e, 0x4d8c, { 0xad, 0x18, 0xb0, 0x21, 0xc5, 0xd9, 0x48, 0xdd } }; + +/// Interface to the sampler object implemented in D3D11 +class ISamplerD3D11 : public Diligent::ISampler +{ +public: + + /// Returns a pointer to the ID3D11SamplerState interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11SamplerState* GetD3D11SamplerState() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/ShaderD3D11.h b/Graphics/GraphicsEngineD3D11/interface/ShaderD3D11.h new file mode 100644 index 00000000..c05cf13f --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/ShaderD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IShaderD3D11 interface + +#include "Shader.h" + +namespace Diligent +{ + +// {C513E83E-B037-405B-8B49-BF8F5C220DEE} +static const Diligent::INTERFACE_ID IID_ShaderD3D11 = +{ 0xc513e83e, 0xb037, 0x405b, { 0x8b, 0x49, 0xbf, 0x8f, 0x5c, 0x22, 0xd, 0xee } }; + +/// Interface to the shader object implemented in D3D11 +class IShaderD3D11 : public Diligent::IShader +{ +public: + + /// Returns a pointer to the ID3D11DeviceChild interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11DeviceChild* GetD3D11Shader() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/SwapChainD3D11.h b/Graphics/GraphicsEngineD3D11/interface/SwapChainD3D11.h new file mode 100644 index 00000000..2419a8ec --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/SwapChainD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ISwapChainD3D11 interface + +#include "SwapChain.h" + +namespace Diligent +{ + +// {4DAF2E76-9204-4DC4-A53A-B00097412D3A} +static const Diligent::INTERFACE_ID IID_SwapChainD3D11 = +{ 0x4daf2e76, 0x9204, 0x4dc4, { 0xa5, 0x3a, 0xb0, 0x0, 0x97, 0x41, 0x2d, 0x3a } }; + +/// Interface to the swap chain object implemented in D3D11 +class ISwapChainD3D11 : public Diligent::ISwapChain +{ +public: + + /// Returns a pointer to the IDXGISwapChain interface of the internal DXGI object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual IDXGISwapChain *GetDXGISwapChain() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/TextureD3D11.h b/Graphics/GraphicsEngineD3D11/interface/TextureD3D11.h new file mode 100644 index 00000000..a08ff236 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/TextureD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ITextureD3D11 interface + +#include "Texture.h" + +namespace Diligent +{ + +// {F3A84CC2-E485-4E72-A08A-437D7FFBA3AB} +static const Diligent::INTERFACE_ID IID_TextureD3D11 = +{ 0xf3a84cc2, 0xe485, 0x4e72, { 0xa0, 0x8a, 0x43, 0x7d, 0x7f, 0xfb, 0xa3, 0xab } }; + +/// Interface to the texture object implemented in D3D11 +class ITextureD3D11 : public Diligent::ITexture +{ +public: + + /// Returns a pointer to the ID3D11Resource interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11Resource* GetD3D11Texture() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/TextureViewD3D11.h b/Graphics/GraphicsEngineD3D11/interface/TextureViewD3D11.h new file mode 100644 index 00000000..7b44ca0b --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/TextureViewD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ITextureViewD3D11 interface + +#include "TextureView.h" + +namespace Diligent +{ + +// {0767EBE4-AD47-4E70-9B65-38C6B9CAC37D} +static const Diligent::INTERFACE_ID IID_TextureViewD3D11 = +{ 0x767ebe4, 0xad47, 0x4e70, { 0x9b, 0x65, 0x38, 0xc6, 0xb9, 0xca, 0xc3, 0x7d } }; + +/// Interface to the texture view object implemented in D3D11 +class ITextureViewD3D11 : public Diligent::ITextureView +{ +public: + + /// Returns a pointer to the ID3D11View interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11View* GetD3D11View() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/VertexDescriptionD3D11.h b/Graphics/GraphicsEngineD3D11/interface/VertexDescriptionD3D11.h new file mode 100644 index 00000000..ab75bfba --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/VertexDescriptionD3D11.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IVertexDescriptionD3D11 interface + +#include "VertexDescription.h" + +namespace Diligent +{ + +// {7BCB2412-60EB-451C-9167-F31B869484C1} +static const Diligent::INTERFACE_ID IID_VertexDescriptionD3D11 = +{ 0x7bcb2412, 0x60eb, 0x451c, { 0x91, 0x67, 0xf3, 0x1b, 0x86, 0x94, 0x84, 0xc1 } }; + +/// Interface to the vertex description object implemented in D3D11 +class IVertexDescriptionD3D11 : public Diligent::IVertexDescription +{ +public: + + /// Returns a pointer to the ID3D11InputLayout interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11InputLayout* GetD3D11InputLayout() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/src/BlendStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/BlendStateD3D11Impl.cpp new file mode 100644 index 00000000..eb336523 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/BlendStateD3D11Impl.cpp @@ -0,0 +1,144 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "BlendStateD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" + +namespace Diligent +{ + +D3D11_BLEND BlendFactorToD3D11Blend( BLEND_FACTOR bf ) +{ + // Note that this code is safe for multithreaded environments since + // bIsInit is set to true only AFTER the entire map is initialized. + static bool bIsInit = false; + static D3D11_BLEND D3D11Blend[BLEND_FACTOR_NUM_FACTORS] = {}; + if( !bIsInit ) + { + // In a multithreaded environment, several threads can potentially enter + // this block. This is not a problem since they will just initialize the + // memory with the same values more than once + D3D11Blend[ BLEND_FACTOR_ZERO ] = D3D11_BLEND_ZERO; + D3D11Blend[ BLEND_FACTOR_ONE ] = D3D11_BLEND_ONE; + D3D11Blend[ BLEND_FACTOR_SRC_COLOR ] = D3D11_BLEND_SRC_COLOR; + D3D11Blend[ BLEND_FACTOR_INV_SRC_COLOR ] = D3D11_BLEND_INV_SRC_COLOR; + D3D11Blend[ BLEND_FACTOR_SRC_ALPHA ] = D3D11_BLEND_SRC_ALPHA; + D3D11Blend[ BLEND_FACTOR_INV_SRC_ALPHA ] = D3D11_BLEND_INV_SRC_ALPHA; + D3D11Blend[ BLEND_FACTOR_DEST_ALPHA ] = D3D11_BLEND_DEST_ALPHA; + D3D11Blend[ BLEND_FACTOR_INV_DEST_ALPHA ] = D3D11_BLEND_INV_DEST_ALPHA; + D3D11Blend[ BLEND_FACTOR_DEST_COLOR ] = D3D11_BLEND_DEST_COLOR; + D3D11Blend[ BLEND_FACTOR_INV_DEST_COLOR ] = D3D11_BLEND_INV_DEST_COLOR; + D3D11Blend[ BLEND_FACTOR_SRC_ALPHA_SAT ] = D3D11_BLEND_SRC_ALPHA_SAT; + D3D11Blend[ BLEND_FACTOR_BLEND_FACTOR ] = D3D11_BLEND_BLEND_FACTOR; + D3D11Blend[ BLEND_FACTOR_INV_BLEND_FACTOR ] = D3D11_BLEND_INV_BLEND_FACTOR; + D3D11Blend[ BLEND_FACTOR_SRC1_COLOR ] = D3D11_BLEND_SRC1_COLOR; + D3D11Blend[ BLEND_FACTOR_INV_SRC1_COLOR ] = D3D11_BLEND_INV_SRC1_COLOR; + D3D11Blend[ BLEND_FACTOR_SRC1_ALPHA ] = D3D11_BLEND_SRC1_ALPHA; + D3D11Blend[ BLEND_FACTOR_INV_SRC1_ALPHA ] = D3D11_BLEND_INV_SRC1_ALPHA; + + bIsInit = true; + } + if( bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS ) + { + auto d3dbf = D3D11Blend[bf]; + VERIFY( d3dbf != 0, "Incorrect blend factor" ); + return d3dbf; + } + else + { + UNEXPECTED("Incorrect blend factor (", bf, ")" ) + return static_cast<D3D11_BLEND>( 0 ); + } +} + +D3D11_BLEND_OP BlendOperation2D3D11BlendOp( BLEND_OPERATION BlendOp ) +{ + static bool bIsInit = false; + static D3D11_BLEND_OP D3D11BlendOp[BLEND_OPERATION_NUM_OPERATIONS] = {}; + if( !bIsInit ) + { + D3D11BlendOp[ BLEND_OPERATION_ADD ] = D3D11_BLEND_OP_ADD; + D3D11BlendOp[ BLEND_OPERATION_SUBTRACT ] = D3D11_BLEND_OP_SUBTRACT; + D3D11BlendOp[ BLEND_OPERATION_REV_SUBTRACT ] = D3D11_BLEND_OP_REV_SUBTRACT; + D3D11BlendOp[ BLEND_OPERATION_MIN ] = D3D11_BLEND_OP_MIN; + D3D11BlendOp[ BLEND_OPERATION_MAX ] = D3D11_BLEND_OP_MAX; + + bIsInit = true; + } + + if( BlendOp > BLEND_OPERATION_UNDEFINED && BlendOp < BLEND_OPERATION_NUM_OPERATIONS ) + { + auto d3dbop = D3D11BlendOp[BlendOp]; + VERIFY( d3dbop != 0, "Incorrect blend operation" ); + return d3dbop; + } + else + { + UNEXPECTED( "Incorrect blend operation (", BlendOp, ")" ) + return static_cast<D3D11_BLEND_OP>(0); + } +} + +BlendStateD3D11Impl::BlendStateD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, + const BlendStateDesc& BlendStateDesc) : + TBlendStateBase(pRenderDeviceD3D11, BlendStateDesc) +{ + D3D11_BLEND_DESC D3D11BSDesc; + D3D11BSDesc.AlphaToCoverageEnable = BlendStateDesc.AlphaToCoverageEnable ? TRUE : FALSE; + D3D11BSDesc.IndependentBlendEnable = BlendStateDesc.IndependentBlendEnable ? TRUE : FALSE; + VERIFY( BlendStateDesc.MaxRenderTargets >= 8, "Number of render targets is expected to be at least 8" ); + for( int i = 0; i < 8; ++i ) + { + const auto& SrcRTDesc = BlendStateDesc.RenderTargets[i]; + auto &DstRTDesc = D3D11BSDesc.RenderTarget[i]; + DstRTDesc.BlendEnable = SrcRTDesc.BlendEnable ? TRUE : FALSE; + + DstRTDesc.SrcBlend = BlendFactorToD3D11Blend(SrcRTDesc.SrcBlend); + DstRTDesc.DestBlend = BlendFactorToD3D11Blend(SrcRTDesc.DestBlend); + DstRTDesc.BlendOp = BlendOperation2D3D11BlendOp(SrcRTDesc.BlendOp); + + DstRTDesc.SrcBlendAlpha = BlendFactorToD3D11Blend(SrcRTDesc.SrcBlendAlpha); + DstRTDesc.DestBlendAlpha = BlendFactorToD3D11Blend(SrcRTDesc.DestBlendAlpha); + DstRTDesc.BlendOpAlpha = BlendOperation2D3D11BlendOp(SrcRTDesc.BlendOpAlpha); + + DstRTDesc.RenderTargetWriteMask = + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_RED) ? D3D11_COLOR_WRITE_ENABLE_RED : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_GREEN) ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_BLUE) ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_ALPHA) ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0); + } + + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateBlendState( &D3D11BSDesc, &m_pd3d11BlendState ), + "Failed to create D3D11 blend state object" ); +} + +BlendStateD3D11Impl::~BlendStateD3D11Impl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( BlendStateD3D11Impl, IID_BlendStateD3D11, TBlendStateBase ) + +} diff --git a/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp new file mode 100644 index 00000000..97905e47 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp @@ -0,0 +1,237 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "BufferD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" +#include "DeviceContextD3D11Impl.h" +#include "D3D11TypeConversions.h" +#include "BufferViewD3D11Impl.h" +#include "GraphicsUtilities.h" + +using namespace Diligent; + +namespace Diligent +{ + +BufferD3D11Impl :: BufferD3D11Impl(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const BufferDesc& BuffDesc, const BufferData &BuffData /*= BufferData()*/) : + TBufferBase(pRenderDeviceD3D11, BuffDesc) +{ +#define LOG_BUFFER_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Buffer \"", BuffDesc.Name ? BuffDesc.Name : "", "\": ", ##__VA_ARGS__); + + if( BuffDesc.Usage == USAGE_STATIC && BuffData.pData == nullptr ) + LOG_BUFFER_ERROR_AND_THROW("Static buffer must be initialized with data at creation time"); + D3D11_BUFFER_DESC D3D11BuffDesc; + D3D11BuffDesc.BindFlags = BindFlagsToD3D11BindFlags(BuffDesc.BindFlags); + D3D11BuffDesc.ByteWidth = BuffDesc.uiSizeInBytes; + D3D11BuffDesc.MiscFlags = 0; + if( BuffDesc.BindFlags & BIND_INDIRECT_DRAW_ARGS ) + { + D3D11BuffDesc.MiscFlags |= D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS; + } + D3D11BuffDesc.Usage = UsageToD3D11Usage(BuffDesc.Usage); + + D3D11BuffDesc.StructureByteStride = 0; + if( (BuffDesc.BindFlags & BIND_UNORDERED_ACCESS) ) + { + if( BuffDesc.Mode == BUFFER_MODE_STRUCTURED ) + { + D3D11BuffDesc.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + D3D11BuffDesc.StructureByteStride = BuffDesc.ElementByteStride; + } + else if( BuffDesc.Mode == BUFFER_MODE_FORMATED ) + { + auto ElementStride = GetValueSize( BuffDesc.Format.ValueType ) * BuffDesc.Format.NumComponents; + VERIFY( m_Desc.ElementByteStride == 0 || m_Desc.ElementByteStride == ElementStride, "Element byte stride does not match buffer format" ); + m_Desc.ElementByteStride = ElementStride; + if( BuffDesc.Format.ValueType == VT_FLOAT32 || BuffDesc.Format.ValueType == VT_FLOAT16 ) + m_Desc.Format.IsNormalized = false; + } + else + { + UNEXPECTED( "Buffer UAV type is not correct" ); + } + } + + D3D11BuffDesc.CPUAccessFlags = CPUAccessFlagsToD3D11CPUAccessFlags( BuffDesc.CPUAccessFlags ); + + D3D11_SUBRESOURCE_DATA InitData; + InitData.pSysMem = BuffData.pData; + InitData.SysMemPitch = BuffData.DataSize; + InitData.SysMemSlicePitch = 0; + + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateBuffer(&D3D11BuffDesc, InitData.pSysMem ? &InitData : nullptr, &m_pd3d11Buffer), + "Failed to create the Direct3D11 buffer" ); +} + +BufferD3D11Impl :: ~BufferD3D11Impl() +{ +} + +IMPLEMENT_QUERY_INTERFACE( BufferD3D11Impl, IID_BufferD3D11, TBufferBase ) + +void BufferD3D11Impl::UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData ) +{ + TBufferBase::UpdateData( pContext, Offset, Size, pData ); + + auto *pd3d11DeviceContext = static_cast<DeviceContextD3D11Impl*>(pContext)->GetD3D11DeviceContext(); + + D3D11_BOX DstBox; + DstBox.left = Offset; + DstBox.right = Offset + Size; + DstBox.top = 0; + DstBox.bottom = 1; + DstBox.front = 0; + DstBox.back = 1; + auto *pDstBox = (Offset == 0 && Size == m_Desc.uiSizeInBytes) ? nullptr : &DstBox; + pd3d11DeviceContext->UpdateSubresource(m_pd3d11Buffer, 0, pDstBox, pData, 0, 0); +} + +void BufferD3D11Impl :: CopyData(IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size) +{ + TBufferBase::CopyData( pContext, pSrcBuffer, SrcOffset, DstOffset, Size ); + + auto *pd3d11DeviceContext = static_cast<DeviceContextD3D11Impl*>(pContext)->GetD3D11DeviceContext(); + auto *pSrBufferD3D11Impl = static_cast<BufferD3D11Impl*>( pSrcBuffer ); + + D3D11_BOX SrcBox; + SrcBox.left = SrcOffset; + SrcBox.right = SrcOffset + Size; + SrcBox.top = 0; + SrcBox.bottom = 1; + SrcBox.front = 0; + SrcBox.back = 1; + pd3d11DeviceContext->CopySubresourceRegion(m_pd3d11Buffer, 0, DstOffset, 0, 0, pSrBufferD3D11Impl->m_pd3d11Buffer, 0, &SrcBox); +} + +void BufferD3D11Impl :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) +{ + TBufferBase::Map( pContext, MapType, MapFlags, pMappedData ); + + auto *pd3d11DeviceContext = static_cast<DeviceContextD3D11Impl*>(pContext)->GetD3D11DeviceContext(); + auto d3d11MapType = MapTypeToD3D11MapType(MapType); + auto d3d11MapFlags = MapFlagsToD3D11MapFlags(MapFlags); + + D3D11_MAPPED_SUBRESOURCE MappedBuff; + HRESULT hr = pd3d11DeviceContext->Map(m_pd3d11Buffer, 0, d3d11MapType, d3d11MapFlags, &MappedBuff); + + pMappedData = SUCCEEDED(hr) ? MappedBuff.pData : nullptr; + + VERIFY( pMappedData || (MapFlags & MAP_FLAG_DO_NOT_WAIT) && (hr == DXGI_ERROR_WAS_STILL_DRAWING), "Map failed" ); +} + +void BufferD3D11Impl::Unmap( IDeviceContext *pContext ) +{ + TBufferBase::Unmap( pContext ); + + auto *pd3d11DeviceContext = static_cast<DeviceContextD3D11Impl*>(pContext)->GetD3D11DeviceContext(); + pd3d11DeviceContext->Unmap(m_pd3d11Buffer, 0); +} + +void BufferD3D11Impl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IBufferView **ppView, bool bIsDefaultView ) +{ + VERIFY( ppView != nullptr, "Null pointer provided" ); + if( !ppView )return; + VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + + *ppView = nullptr; + + try + { + BufferViewDesc ViewDesc = OrigViewDesc; + if( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS ) + { + CComPtr<ID3D11UnorderedAccessView> pUAV; + CreateUAV( ViewDesc, &pUAV ); + *ppView = new BufferViewD3D11Impl( GetDevice(), ViewDesc, this, pUAV, bIsDefaultView ); + } + else if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE ) + { + CComPtr<ID3D11ShaderResourceView> pSRV; + CreateSRV( ViewDesc, &pSRV ); + *ppView = new BufferViewD3D11Impl( GetDevice(), ViewDesc, this, pSRV, bIsDefaultView ); + } + + if( !bIsDefaultView && *ppView ) + (*ppView)->AddRef(); + } + catch( const std::runtime_error & ) + { + const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType); + LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name, "\"" ) + } +} + +void BufferD3D11Impl::CreateUAV( BufferViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ) +{ + D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; + memset( &D3D11_UAVDesc, 0, sizeof(D3D11_UAVDesc) ); + const auto &BuffFmt = m_Desc.Format; + if( m_Desc.Mode == BUFFER_MODE_FORMATED ) + D3D11_UAVDesc.Format = TypeToDXGI_Format( BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized ); + + CorrectBufferViewDesc( UAVDesc ); + if( UAVDesc.ByteOffset != 0 ) + { + VERIFY( m_Desc.Mode == BUFFER_MODE_STRUCTURED, "Non-zero byte offset is only supported for structured buffers" ); + } + VERIFY( UAVDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); + VERIFY( (UAVDesc.ByteOffset % m_Desc.ElementByteStride) == 0, "Byte offest is not multiple of element byte stride" ); + VERIFY( (UAVDesc.ByteWidth % m_Desc.ElementByteStride) == 0, "Byte width is not multiple of element byte stride" ); + D3D11_UAVDesc.Buffer.FirstElement = UAVDesc.ByteOffset / m_Desc.ElementByteStride; + D3D11_UAVDesc.Buffer.NumElements = UAVDesc.ByteWidth / m_Desc.ElementByteStride; + D3D11_UAVDesc.Buffer.Flags = 0; // D3D11_BUFFER_UAV_FLAG_RAW, D3D11_BUFFER_UAV_FLAG_APPEND, D3D11_BUFFER_UAV_FLAG_COUNTER + D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Buffer, &D3D11_UAVDesc, ppD3D11UAV ), + "Failed to create D3D11 unordered access view" ); +} + +void BufferD3D11Impl::CreateSRV( struct BufferViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ) +{ + D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; + memset( &D3D11_SRVDesc, 0, sizeof( D3D11_SRVDesc ) ); + const auto &BuffFmt = m_Desc.Format; + if( m_Desc.Mode == BUFFER_MODE_FORMATED ) + D3D11_SRVDesc.Format = TypeToDXGI_Format( BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized ); + + CorrectBufferViewDesc( SRVDesc ); + if( SRVDesc.ByteOffset != 0 ) + { + VERIFY( m_Desc.Mode == BUFFER_MODE_STRUCTURED, "Non-zero byte offset is only supported for structured buffers" ); + } + VERIFY( SRVDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); + VERIFY( (SRVDesc.ByteOffset % m_Desc.ElementByteStride) == 0, "Byte offest is not multiple of element byte stride" ); + VERIFY( (SRVDesc.ByteWidth % m_Desc.ElementByteStride) == 0, "Byte width is not multiple of element byte stride" ); + D3D11_SRVDesc.Buffer.FirstElement = SRVDesc.ByteOffset / m_Desc.ElementByteStride; + D3D11_SRVDesc.Buffer.NumElements = SRVDesc.ByteWidth / m_Desc.ElementByteStride; + D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Buffer, &D3D11_SRVDesc, ppD3D11SRV ), + "Failed to create D3D11 shader resource view" ); +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp new file mode 100644 index 00000000..6f8239d8 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp @@ -0,0 +1,47 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "BufferViewD3D11Impl.h" + +namespace Diligent +{ + +BufferViewD3D11Impl::BufferViewD3D11Impl( IRenderDevice *pDevice, + const BufferViewDesc& ViewDesc, + IBuffer *pBuffer, + ID3D11View* pD3D11View, + bool bIsDefaultView ) : + TBufferViewBase( pDevice, ViewDesc, pBuffer, bIsDefaultView ), + m_pD3D11View( pD3D11View ) +{ +} + +ID3D11View* BufferViewD3D11Impl::GetD3D11View() +{ + return m_pD3D11View; +} + +IMPLEMENT_QUERY_INTERFACE( BufferViewD3D11Impl, IID_BufferViewD3D11, TBufferViewBase ) + +} diff --git a/Graphics/GraphicsEngineD3D11/src/D3D11DebugUtilities.cpp b/Graphics/GraphicsEngineD3D11/src/D3D11DebugUtilities.cpp new file mode 100644 index 00000000..686df365 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/D3D11DebugUtilities.cpp @@ -0,0 +1,198 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "D3D11DebugUtilities.h" +#include "TextureViewD3D11.h" +#include "BufferViewD3D11.h" +#include "BufferD3D11.h" +#include "SamplerD3D11.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +#ifdef VERIFY_RESOURCE_ARRAYS + +template<typename TResourceArr, typename TD3D11ResourceArr, typename TTestProc> +void dbgVerifyResourceArraysInternal( TResourceArr &Resources, TD3D11ResourceArr& d3d11Resources, TTestProc TestProc ) +{ + VERIFY( Resources.size() == d3d11Resources.size(), "Inconsistent resource array sizes (", Resources.size(), ",", d3d11Resources.size(), ")" ); + auto NumSlots = std::min(Resources.size(), d3d11Resources.size()); + for( Uint32 Slot = 0; Slot < NumSlots; ++Slot ) + { + auto &Res = Resources.at(Slot); + const auto &d3d11Res = d3d11Resources.at( Slot ); + TestProc( Slot, Res, d3d11Res ); + } +} + +static const Char* GetD3D11ResName( const ID3D11ShaderResourceView* ){ return "SRV"; } +static const Char* GetD3D11ResName( const ID3D11UnorderedAccessView* ){ return "UAV"; } +static const Char* GetD3D11ResName( const ID3D11Buffer* ){ return "constant buffer"; } +static const Char* GetD3D11ResName( const ID3D11SamplerState* ){ return "sampler"; } + +template<typename TBoundResourceType, typename TD3D11ResourceType> +class dbgVerifyResourceViewArrays +{ +public: + dbgVerifyResourceViewArrays( TEXTURE_VIEW_TYPE TVT, BUFFER_VIEW_TYPE BVT, IShader *pShader ) : + TexViewType( TVT ), + BuffViewType( BVT ), + ShaderTypeName(GetShaderTypeLiteralName(pShader->GetDesc().ShaderType)), + ShaderName(pShader->GetDesc().Name) + {} + + void operator()( int Slot, const TBoundResourceType& BoundRes, const TD3D11ResourceType* d3d11View ) + { + TD3D11ResourceType *pD3D11ResTypeMarker = nullptr; +#define VERFIY_RESOURCE_BINDING(Exp, Intro, Res, ...) \ + VERIFY(Exp, Intro, " \"", Res->GetDesc().Name, "\" bound as ", GetD3D11ResName(pD3D11ResTypeMarker)," to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot, ' ', __VA_ARGS__) + + if( !d3d11View ) + { + VERFIY_RESOURCE_BINDING( !BoundRes.pResource, "Unexpected non-null resource", BoundRes.pResource ) + VERFIY_RESOURCE_BINDING( !BoundRes.pView, "Unexpected non-null resource view", BoundRes.pView ) + } + + if( BoundRes.pView ) + { + auto ncView = const_cast<IDeviceObject*>(BoundRes.pView.RawPtr()); + RefCntAutoPtr<ITextureViewD3D11> pTexView; + ncView->QueryInterface( IID_TextureViewD3D11, reinterpret_cast<IObject**>(static_cast<ITextureViewD3D11**>(&pTexView)) ); + RefCntAutoPtr<IBufferViewD3D11> pBuffView; + ncView->QueryInterface( IID_BufferViewD3D11, reinterpret_cast<IObject**>(static_cast<IBufferViewD3D11**>(&pBuffView)) ); + VERFIY_RESOURCE_BINDING( pTexView || pBuffView, "Resource", ncView, "is expected to be a texture view or a buffer view" ); + if( pTexView ) + { + auto ViewType = pTexView->GetDesc().ViewType; + VERFIY_RESOURCE_BINDING( ViewType == TexViewType, "Texture view", ncView, "has incorrect type: ", GetTexViewTypeLiteralName( TexViewType ), " is expected, while ", GetTexViewTypeLiteralName( ViewType ), " provided" ); + auto *d3d11RefView = pTexView->GetD3D11View(); + VERFIY_RESOURCE_BINDING( d3d11RefView == d3d11View && BoundRes.pd3d11View.RawPtr() == d3d11RefView, "Texture view", ncView, "does not match D3D11 resoruce" ); + auto *pTex = pTexView->GetTexture(); + VERFIY_RESOURCE_BINDING( pTex == BoundRes.pResource, "Texture view", ncView, "is not the view of resource \"", BoundRes.pResource->GetDesc().Name, "\"" ); + } + + if( pBuffView ) + { + auto ViewType = pBuffView->GetDesc().ViewType; + VERFIY_RESOURCE_BINDING( ViewType == BuffViewType, "Buffer view", ncView, "has incorrect type: ", GetBufferViewTypeLiteralName( BuffViewType ), " is expected, while ", GetBufferViewTypeLiteralName( ViewType ), " provided" ); + auto *d3d11RefView = pBuffView->GetD3D11View(); + VERFIY_RESOURCE_BINDING( d3d11RefView == d3d11View && BoundRes.pd3d11View.RawPtr() == d3d11RefView, "Buffer view", ncView, "does not match D3D11 resource" ); + auto *pBuf = pBuffView->GetBuffer(); + VERFIY_RESOURCE_BINDING( pBuf == BoundRes.pResource, "Buffer view", ncView, "is not the view of resource \"", BoundRes.pResource->GetDesc().Name, "\"" ); + } + } + else + { + VERIFY( !BoundRes.pResource, "Unexpected non-null resource bound to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot); + VERIFY( !BoundRes.pd3d11View, "Unexpected non-null D3D11 resource view bound to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot); + } + } +private: + TEXTURE_VIEW_TYPE TexViewType; + BUFFER_VIEW_TYPE BuffViewType; + const Char* ShaderTypeName; + const char* ShaderName; +}; + +void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundSRV >&SRVs, const std::vector<ID3D11ShaderResourceView*> d3d11SRVs, IShader *pShader ) +{ + dbgVerifyResourceArraysInternal(SRVs, d3d11SRVs, dbgVerifyResourceViewArrays<ShaderD3D11Impl::BoundSRV, ID3D11ShaderResourceView>(TEXTURE_VIEW_SHADER_RESOURCE, BUFFER_VIEW_SHADER_RESOURCE, pShader)); +} + +void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundUAV >&UAVs, const std::vector<ID3D11UnorderedAccessView*> d3d11UAVs, IShader *pShader ) +{ + dbgVerifyResourceArraysInternal(UAVs, d3d11UAVs, dbgVerifyResourceViewArrays<ShaderD3D11Impl::BoundUAV, ID3D11UnorderedAccessView>(TEXTURE_VIEW_UNORDERED_ACCESS, BUFFER_VIEW_UNORDERED_ACCESS, pShader)); +} + +void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundCB >&CBs, const std::vector<ID3D11Buffer*> d3d11CBs, IShader *pShader ) +{ + const auto* ShaderTypeName = GetShaderTypeLiteralName( pShader->GetDesc().ShaderType ); + const auto &ShaderName = pShader->GetDesc().Name; + ID3D11Buffer *pD3D11ResTypeMarker = nullptr; + + dbgVerifyResourceArraysInternal( CBs, d3d11CBs, + [&]( int Slot, const ShaderD3D11Impl::BoundCB& CB, const ID3D11Buffer* d3d11CB ) + { + if( !d3d11CB ) + { + VERFIY_RESOURCE_BINDING( !CB.pBuff, "Unexpected non-null resource", CB.pBuff ) + } + + if( CB.pBuff ) + { + auto ncCB = const_cast<IDeviceObject*>(CB.pBuff.RawPtr()); + RefCntAutoPtr<IBufferD3D11> pBuff; + ncCB->QueryInterface( IID_BufferD3D11, reinterpret_cast<IObject**>(static_cast<IBufferD3D11**>(&pBuff)) ); + VERFIY_RESOURCE_BINDING( pBuff, "Resource", ncCB, "is expected to be a buffer" ); + if( pBuff ) + { + auto *d3d11RefBuff = pBuff->GetD3D11Buffer(); + VERFIY_RESOURCE_BINDING( d3d11RefBuff == d3d11CB && d3d11RefBuff == CB.pd3d11Buff, "Constant buffer", ncCB, "does not match D3D11 buffer" ); + } + } + else + { + VERIFY( !d3d11CB, "Unexpected non-null D3D11 buffer bound to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot); + } + } + ); +} + +void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundSampler >&Samplers, const std::vector<ID3D11SamplerState*> d3d11Samplers, IShader *pShader ) +{ + const auto* ShaderTypeName = GetShaderTypeLiteralName( pShader->GetDesc().ShaderType ); + const auto &ShaderName = pShader->GetDesc().Name; + ID3D11SamplerState *pD3D11ResTypeMarker = nullptr; + + dbgVerifyResourceArraysInternal( Samplers, d3d11Samplers, + [&]( int Slot, const ShaderD3D11Impl::BoundSampler& Sampler, const ID3D11SamplerState* d3d11Sampler ) + { + if( !d3d11Sampler ) + { + VERFIY_RESOURCE_BINDING( !Sampler.pSampler, "Unexpected non-null resource", Sampler.pSampler ) + } + if( Sampler.pSampler ) + { + auto ncSampler = const_cast<IDeviceObject*>(Sampler.pSampler.RawPtr()); + RefCntAutoPtr<ISamplerD3D11> pSamplerD3D11; + ncSampler->QueryInterface( IID_SamplerD3D11, reinterpret_cast<IObject**>(static_cast<ISamplerD3D11**>(&pSamplerD3D11)) ); + VERFIY_RESOURCE_BINDING( pSamplerD3D11, "Resource", ncSampler, "is expected to be a sampler" ); + if( pSamplerD3D11 ) + { + auto *d3d11RefSampler = pSamplerD3D11->GetD3D11SamplerState(); + VERFIY_RESOURCE_BINDING( d3d11RefSampler == d3d11Sampler && d3d11RefSampler == Sampler.pd3d11Sampler, "Sampler", ncSampler, "does not match D3D11 sampler" ); + } + } + else + { + VERIFY( !d3d11Sampler, "Unexpected non-null D3D11 sampler bound to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot ); + } + } + ); +} + +#endif + +} diff --git a/Graphics/GraphicsEngineD3D11/src/D3D11TypeConversions.cpp b/Graphics/GraphicsEngineD3D11/src/D3D11TypeConversions.cpp new file mode 100644 index 00000000..ac6265f2 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/D3D11TypeConversions.cpp @@ -0,0 +1,504 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "D3D11TypeConversions.h" + +namespace Diligent +{ + +DXGI_FORMAT TypeToDXGI_Format(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized) +{ + switch(ValType) + { + case VT_FLOAT16: + { + VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_FLOAT; + case 2: return DXGI_FORMAT_R16G16_FLOAT; + case 4: return DXGI_FORMAT_R16G16B16A16_FLOAT; + default: UNEXPECTED("Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + + case VT_FLOAT32: + { + VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R32_FLOAT; + case 2: return DXGI_FORMAT_R32G32_FLOAT; + case 3: return DXGI_FORMAT_R32G32B32_FLOAT; + case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + + case VT_INT32: + { + VERIFY( !bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R32_SINT; + case 2: return DXGI_FORMAT_R32G32_SINT; + case 3: return DXGI_FORMAT_R32G32B32_SINT; + case 4: return DXGI_FORMAT_R32G32B32A32_SINT; + default: UNEXPECTED("Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + + case VT_UINT32: + { + VERIFY( !bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R32_UINT; + case 2: return DXGI_FORMAT_R32G32_UINT; + case 3: return DXGI_FORMAT_R32G32B32_UINT; + case 4: return DXGI_FORMAT_R32G32B32A32_UINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + + case VT_INT16: + { + if( bIsNormalized ) + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_SNORM; + case 2: return DXGI_FORMAT_R16G16_SNORM; + case 4: return DXGI_FORMAT_R16G16B16A16_SNORM; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + else + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_SINT; + case 2: return DXGI_FORMAT_R16G16_SINT; + case 4: return DXGI_FORMAT_R16G16B16A16_SINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + } + + case VT_UINT16: + { + if( bIsNormalized ) + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_UNORM; + case 2: return DXGI_FORMAT_R16G16_UNORM; + case 4: return DXGI_FORMAT_R16G16B16A16_UNORM; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + else + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_UINT; + case 2: return DXGI_FORMAT_R16G16_UINT; + case 4: return DXGI_FORMAT_R16G16B16A16_UINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + } + + case VT_INT8: + { + if( bIsNormalized ) + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R8_SNORM; + case 2: return DXGI_FORMAT_R8G8_SNORM; + case 4: return DXGI_FORMAT_R8G8B8A8_SNORM; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + else + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R8_SINT; + case 2: return DXGI_FORMAT_R8G8_SINT; + case 4: return DXGI_FORMAT_R8G8B8A8_SINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + } + + case VT_UINT8: + { + if( bIsNormalized ) + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R8_UNORM; + case 2: return DXGI_FORMAT_R8G8_UNORM; + case 4: return DXGI_FORMAT_R8G8B8A8_UNORM; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + else + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R8_UINT; + case 2: return DXGI_FORMAT_R8G8_UINT; + case 4: return DXGI_FORMAT_R8G8B8A8_UINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + } + + default: UNEXPECTED( "Unusupported format" ); return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT CorrectDXGIFormat( DXGI_FORMAT DXGIFormat, Uint32 BindFlags ) +{ + if( (BindFlags & BIND_DEPTH_STENCIL) && (BindFlags != BIND_DEPTH_STENCIL) ) + { + switch( DXGIFormat ) + { + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_D32_FLOAT: + DXGIFormat = DXGI_FORMAT_R32_TYPELESS; + break; + + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_D16_UNORM: + DXGIFormat = DXGI_FORMAT_R16_TYPELESS; + break; + + default: + UNEXPECTED( "Unsupported format" ); + break; + } + } + + if( BindFlags == BIND_DEPTH_STENCIL ) + { + switch( DXGIFormat ) + { + case DXGI_FORMAT_R32_FLOAT: + DXGIFormat = DXGI_FORMAT_D32_FLOAT; + break; + + case DXGI_FORMAT_R16_UNORM: + DXGIFormat = DXGI_FORMAT_D16_UNORM; + break; + } + } + + if( BindFlags == BIND_SHADER_RESOURCE || BindFlags == BIND_UNORDERED_ACCESS ) + { + switch( DXGIFormat ) + { + case DXGI_FORMAT_D32_FLOAT: + DXGIFormat = DXGI_FORMAT_R32_FLOAT; + break; + + case DXGI_FORMAT_D16_UNORM: + DXGIFormat = DXGI_FORMAT_R16_UNORM; + break; + } + } + + return DXGIFormat; +} + +DXGI_FORMAT TexFormatToDXGI_Format(TEXTURE_FORMAT TexFormat, Uint32 BindFlags) +{ + static Bool bFormatMapIntialized = false; + static DXGI_FORMAT FmtToDXGIFmtMap[TEX_FORMAT_NUM_FORMATS] = {DXGI_FORMAT_UNKNOWN}; + if( !bFormatMapIntialized ) + { + FmtToDXGIFmtMap[ TEX_FORMAT_UNKNOWN ] = DXGI_FORMAT_UNKNOWN; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_TYPELESS ] = DXGI_FORMAT_R32G32B32A32_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_FLOAT ] = DXGI_FORMAT_R32G32B32A32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_UINT ] = DXGI_FORMAT_R32G32B32A32_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_SINT ] = DXGI_FORMAT_R32G32B32A32_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_TYPELESS ] = DXGI_FORMAT_R32G32B32_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_FLOAT ] = DXGI_FORMAT_R32G32B32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_UINT ] = DXGI_FORMAT_R32G32B32_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_SINT ] = DXGI_FORMAT_R32G32B32_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_TYPELESS ] = DXGI_FORMAT_R16G16B16A16_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_FLOAT ] = DXGI_FORMAT_R16G16B16A16_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_UNORM ] = DXGI_FORMAT_R16G16B16A16_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_UINT ] = DXGI_FORMAT_R16G16B16A16_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_SNORM ] = DXGI_FORMAT_R16G16B16A16_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_SINT ] = DXGI_FORMAT_R16G16B16A16_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RG32_TYPELESS ] = DXGI_FORMAT_R32G32_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RG32_FLOAT ] = DXGI_FORMAT_R32G32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG32_UINT ] = DXGI_FORMAT_R32G32_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG32_SINT ] = DXGI_FORMAT_R32G32_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R32G8X24_TYPELESS ] = DXGI_FORMAT_R32G8X24_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_D32_FLOAT_S8X24_UINT ] = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS ]= DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_X32_TYPELESS_G8X24_UINT ]= DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_TYPELESS ] = DXGI_FORMAT_R10G10B10A2_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_UNORM ] = DXGI_FORMAT_R10G10B10A2_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_UINT ] = DXGI_FORMAT_R10G10B10A2_UINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R11G11B10_FLOAT ] = DXGI_FORMAT_R11G11B10_FLOAT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_TYPELESS ] = DXGI_FORMAT_R8G8B8A8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UNORM ] = DXGI_FORMAT_R8G8B8A8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UNORM_SRGB ] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UINT ] = DXGI_FORMAT_R8G8B8A8_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_SNORM ] = DXGI_FORMAT_R8G8B8A8_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_SINT ] = DXGI_FORMAT_R8G8B8A8_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_TYPELESS ] = DXGI_FORMAT_R16G16_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_FLOAT ] = DXGI_FORMAT_R16G16_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_UNORM ] = DXGI_FORMAT_R16G16_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_UINT ] = DXGI_FORMAT_R16G16_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_SNORM ] = DXGI_FORMAT_R16G16_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_SINT ] = DXGI_FORMAT_R16G16_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R32_TYPELESS ] = DXGI_FORMAT_R32_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_D32_FLOAT ] = DXGI_FORMAT_D32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_R32_FLOAT ] = DXGI_FORMAT_R32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_R32_UINT ] = DXGI_FORMAT_R32_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R32_SINT ] = DXGI_FORMAT_R32_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R24G8_TYPELESS ] = DXGI_FORMAT_R24G8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_D24_UNORM_S8_UINT ] = DXGI_FORMAT_D24_UNORM_S8_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R24_UNORM_X8_TYPELESS ] = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_X24_TYPELESS_G8_UINT ] = DXGI_FORMAT_X24_TYPELESS_G8_UINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_TYPELESS ] = DXGI_FORMAT_R8G8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_UNORM ] = DXGI_FORMAT_R8G8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_UINT ] = DXGI_FORMAT_R8G8_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_SNORM ] = DXGI_FORMAT_R8G8_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_SINT ] = DXGI_FORMAT_R8G8_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R16_TYPELESS ] = DXGI_FORMAT_R16_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_FLOAT ] = DXGI_FORMAT_R16_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_D16_UNORM ] = DXGI_FORMAT_D16_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_UNORM ] = DXGI_FORMAT_R16_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_UINT ] = DXGI_FORMAT_R16_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_SNORM ] = DXGI_FORMAT_R16_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_SINT ] = DXGI_FORMAT_R16_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R8_TYPELESS ] = DXGI_FORMAT_R8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_R8_UNORM ] = DXGI_FORMAT_R8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R8_UINT ] = DXGI_FORMAT_R8_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R8_SNORM ] = DXGI_FORMAT_R8_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R8_SINT ] = DXGI_FORMAT_R8_SINT; + FmtToDXGIFmtMap[ TEX_FORMAT_A8_UNORM ] = DXGI_FORMAT_A8_UNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_R1_UNORM ] = DXGI_FORMAT_R1_UNORM ; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB9E5_SHAREDEXP ] = DXGI_FORMAT_R9G9B9E5_SHAREDEXP; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_B8G8_UNORM ] = DXGI_FORMAT_R8G8_B8G8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_G8R8_G8B8_UNORM ] = DXGI_FORMAT_G8R8_G8B8_UNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_BC1_TYPELESS ] = DXGI_FORMAT_BC1_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC1_UNORM ] = DXGI_FORMAT_BC1_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC1_UNORM_SRGB ] = DXGI_FORMAT_BC1_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_BC2_TYPELESS ] = DXGI_FORMAT_BC2_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC2_UNORM ] = DXGI_FORMAT_BC2_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC2_UNORM_SRGB ] = DXGI_FORMAT_BC2_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_BC3_TYPELESS ] = DXGI_FORMAT_BC3_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC3_UNORM ] = DXGI_FORMAT_BC3_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC3_UNORM_SRGB ] = DXGI_FORMAT_BC3_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_BC4_TYPELESS ] = DXGI_FORMAT_BC4_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC4_UNORM ] = DXGI_FORMAT_BC4_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC4_SNORM ] = DXGI_FORMAT_BC4_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC5_TYPELESS ] = DXGI_FORMAT_BC5_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC5_UNORM ] = DXGI_FORMAT_BC5_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC5_SNORM ] = DXGI_FORMAT_BC5_SNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_B5G6R5_UNORM ] = DXGI_FORMAT_B5G6R5_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_B5G5R5A1_UNORM ] = DXGI_FORMAT_B5G5R5A1_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_UNORM ] = DXGI_FORMAT_B8G8R8A8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_UNORM ] = DXGI_FORMAT_B8G8R8X8_UNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ]= DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_TYPELESS ] = DXGI_FORMAT_B8G8R8A8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_UNORM_SRGB ] = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_TYPELESS ] = DXGI_FORMAT_B8G8R8X8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_UNORM_SRGB ] = DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_TYPELESS ] = DXGI_FORMAT_BC6H_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_UF16 ] = DXGI_FORMAT_BC6H_UF16; + FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_SF16 ] = DXGI_FORMAT_BC6H_SF16; + FmtToDXGIFmtMap[ TEX_FORMAT_BC7_TYPELESS ] = DXGI_FORMAT_BC7_TYPELESS ; + FmtToDXGIFmtMap[ TEX_FORMAT_BC7_UNORM ] = DXGI_FORMAT_BC7_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC7_UNORM_SRGB ] = DXGI_FORMAT_BC7_UNORM_SRGB; + + bFormatMapIntialized = true; + } + + if( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS ) + { + auto DXGIFormat = FmtToDXGIFmtMap[TexFormat]; + VERIFY( TexFormat == TEX_FORMAT_UNKNOWN || DXGIFormat != DXGI_FORMAT_UNKNOWN, "Unsupported texture format" ); + if( BindFlags != 0 ) + DXGIFormat = CorrectDXGIFormat( DXGIFormat, BindFlags ); + return DXGIFormat; + } + else + { + UNEXPECTED( "Texture format (", TexFormat, ") is out of allowed range [0, ", TEX_FORMAT_NUM_FORMATS-1, "]" ); + return DXGI_FORMAT_UNKNOWN; + } +} + +D3D11_FILTER FilterTypeToD3D11Filter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter) +{ + switch( MinFilter ) + { + case FILTER_TYPE_POINT: + if( MagFilter == FILTER_TYPE_POINT ) + { + if( MipFilter == FILTER_TYPE_POINT ) + return D3D11_FILTER_MIN_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_LINEAR ) + return D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_LINEAR ) + { + if( MipFilter == FILTER_TYPE_POINT ) + return D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_LINEAR ) + return D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_LINEAR: + if( MagFilter == FILTER_TYPE_POINT ) + { + if( MipFilter == FILTER_TYPE_POINT ) + return D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_LINEAR ) + return D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_LINEAR ) + { + if( MipFilter == FILTER_TYPE_POINT ) + return D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_LINEAR ) + return D3D11_FILTER_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_ANISOTROPIC: + VERIFY( MagFilter == FILTER_TYPE_ANISOTROPIC && MipFilter == FILTER_TYPE_ANISOTROPIC, + "For anistropic filtering, all filters must be anisotropic" ); + return D3D11_FILTER_ANISOTROPIC; + break; + + case FILTER_TYPE_COMPARISON_POINT: + if( MagFilter == FILTER_TYPE_COMPARISON_POINT ) + { + if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) + return D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) + return D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_COMPARISON_LINEAR ) + { + if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) + return D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) + return D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_COMPARISON_LINEAR: + if( MagFilter == FILTER_TYPE_COMPARISON_POINT ) + { + if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) + return D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) + return D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_COMPARISON_LINEAR ) + { + if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) + return D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) + return D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_COMPARISON_ANISOTROPIC: + VERIFY( MagFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC && MipFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC, + "For comparison anistropic filtering, all filters must be anisotropic" ); + return D3D11_FILTER_COMPARISON_ANISOTROPIC; + break; + } + + UNEXPECTED( "Unsupported filter combination" ); + return D3D11_FILTER_MIN_MAG_MIP_POINT; +} + +D3D11_STENCIL_OP StencilOpToD3D11StencilOp( STENCIL_OP StencilOp ) +{ + static bool bIsInit = false; + static D3D11_STENCIL_OP StOp2D3D11StOpMap[STENCIL_OP_NUM_OPS] = {}; + if( !bIsInit ) + { + StOp2D3D11StOpMap[ STENCIL_OP_KEEP ] = D3D11_STENCIL_OP_KEEP; + StOp2D3D11StOpMap[ STENCIL_OP_ZERO ] = D3D11_STENCIL_OP_ZERO; + StOp2D3D11StOpMap[ STENCIL_OP_REPLACE ] = D3D11_STENCIL_OP_REPLACE; + StOp2D3D11StOpMap[ STENCIL_OP_INCR_SAT ] = D3D11_STENCIL_OP_INCR_SAT; + StOp2D3D11StOpMap[ STENCIL_OP_DECR_SAT ] = D3D11_STENCIL_OP_DECR_SAT; + StOp2D3D11StOpMap[ STENCIL_OP_INVERT ] = D3D11_STENCIL_OP_INVERT; + StOp2D3D11StOpMap[ STENCIL_OP_INCR_WRAP] = D3D11_STENCIL_OP_INCR; + StOp2D3D11StOpMap[ STENCIL_OP_DECR_WRAP] = D3D11_STENCIL_OP_DECR; + + bIsInit = true; + } + + if( StencilOp > STENCIL_OP_UNDEFINED && StencilOp < STENCIL_OP_NUM_OPS ) + { + auto D3D11StencilOp = StOp2D3D11StOpMap[StencilOp]; + VERIFY( D3D11StencilOp != 0, "Unexpected stencil op" ); + return D3D11StencilOp; + } + else + { + UNEXPECTED( "Stencil operation (", StencilOp, ") is out of allowed range [1, ", STENCIL_OP_NUM_OPS - 1, "]" ) + return static_cast<D3D11_STENCIL_OP>(0); + } +} + + +} diff --git a/Graphics/GraphicsEngineD3D11/src/DLLMain.cpp b/Graphics/GraphicsEngineD3D11/src/DLLMain.cpp new file mode 100644 index 00000000..373d1570 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/DLLMain.cpp @@ -0,0 +1,49 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) +{ + switch( ul_reason_for_call ) + { + case DLL_PROCESS_ATTACH: + #if defined(_DEBUG) || defined(DEBUG) + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); + #endif + break; + + case DLL_THREAD_ATTACH: + break; + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/src/DSStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DSStateD3D11Impl.cpp new file mode 100644 index 00000000..218664c1 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/DSStateD3D11Impl.cpp @@ -0,0 +1,66 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "DSStateD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" + +namespace Diligent +{ + +D3D11_DEPTH_STENCILOP_DESC StencilOpDesc2D3D11StencilOpDesc(const StencilOpDesc &StOpDesc) +{ + D3D11_DEPTH_STENCILOP_DESC D3D11StOpDesc; + D3D11StOpDesc.StencilFailOp = StencilOpToD3D11StencilOp( StOpDesc.StencilFailOp ); + D3D11StOpDesc.StencilDepthFailOp = StencilOpToD3D11StencilOp( StOpDesc.StencilDepthFailOp ); + D3D11StOpDesc.StencilPassOp = StencilOpToD3D11StencilOp( StOpDesc.StencilPassOp ); + D3D11StOpDesc.StencilFunc = ComparisonFuncToD3D11ComparisonFunc( StOpDesc.StencilFunc ); + return D3D11StOpDesc; +} + +DSStateD3D11Impl::DSStateD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const DepthStencilStateDesc& DepthStencilStateDesc) : + TDepthStencilStateBase(pRenderDeviceD3D11, DepthStencilStateDesc) +{ + D3D11_DEPTH_STENCIL_DESC D3D11DSSDesc; + D3D11DSSDesc.DepthEnable = DepthStencilStateDesc.DepthEnable ? TRUE : FALSE; + D3D11DSSDesc.DepthWriteMask = DepthStencilStateDesc.DepthWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; + D3D11DSSDesc.DepthFunc = ComparisonFuncToD3D11ComparisonFunc( DepthStencilStateDesc.DepthFunc ); + D3D11DSSDesc.StencilEnable = DepthStencilStateDesc.StencilEnable ? TRUE : FALSE; + D3D11DSSDesc.StencilReadMask = DepthStencilStateDesc.StencilReadMask; + D3D11DSSDesc.StencilWriteMask = DepthStencilStateDesc.StencilWriteMask; + D3D11DSSDesc.FrontFace = StencilOpDesc2D3D11StencilOpDesc( DepthStencilStateDesc.FrontFace ); + D3D11DSSDesc.BackFace = StencilOpDesc2D3D11StencilOpDesc( DepthStencilStateDesc.BackFace ); + + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateDepthStencilState( &D3D11DSSDesc, &m_pd3d11DepthStencilState ), + "Failed to create D3D11 depth stencil state" ); +} + +DSStateD3D11Impl::~DSStateD3D11Impl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( DSStateD3D11Impl, IID_DepthStencilStateD3D11, TDepthStencilStateBase ) + +} diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp new file mode 100644 index 00000000..a6e14dd5 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -0,0 +1,1308 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "DeviceContextD3D11Impl.h" +#include "BufferD3D11Impl.h" +#include "VertexDescD3D11Impl.h" +#include "ShaderD3D11Impl.h" +#include "Texture1D_D3D11.h" +#include "Texture2D_D3D11.h" +#include "Texture3D_D3D11.h" +#include "SamplerD3D11Impl.h" +#include "D3D11TypeConversions.h" +#include "TextureViewD3D11Impl.h" +#include "DSStateD3D11Impl.h" +#include "RasterizerStateD3D11Impl.h" +#include "BlendStateD3D11Impl.h" +#include "DSStateD3D11Impl.h" +#include "SwapChainD3D11Impl.h" +#include "D3D11DebugUtilities.h" + +using namespace Diligent; + +namespace Diligent +{ + + DeviceContextD3D11Impl::DeviceContextD3D11Impl( IRenderDevice *pDevice, ID3D11DeviceContext *pd3d11DeviceContext ) : + TDeviceContextBase(pDevice), + m_pd3d11DeviceContext( pd3d11DeviceContext ), + m_BoundD3D11IndexFmt(DXGI_FORMAT_UNKNOWN), + m_BoundD3D11IndexDataStartOffset(0) + { + for( int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType ) + { + m_BoundCBs [ShaderType].reserve( D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ); // 14 + m_BoundD3D11CBs[ShaderType].reserve( D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ); // 14 + + m_BoundSamplers [ShaderType].reserve( D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT );// 16 + m_BoundD3D11Samplers[ShaderType].reserve( D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT );// 16 + + m_BoundSRVs [ShaderType].reserve( D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT );// 128 + m_BoundD3D11SRVs[ShaderType].reserve( D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT );// 128 + + m_BoundUAVs [ShaderType].reserve( D3D11_PS_CS_UAV_REGISTER_COUNT );// 8 + m_BoundD3D11UAVs[ShaderType].reserve( D3D11_PS_CS_UAV_REGISTER_COUNT );// 8 + } + } + + IMPLEMENT_QUERY_INTERFACE( DeviceContextD3D11Impl, IID_DeviceContextD3D11, TDeviceContextBase ) + + void DeviceContextD3D11Impl::SetShaders( IShader **ppShaders, Uint32 NumShadersToSet ) + { + TDeviceContextBase::SetShaders( ppShaders, NumShadersToSet ); + } + + void DeviceContextD3D11Impl::BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) + { + TDeviceContextBase::BindShaderResources( pResourceMapping, Flags ); + for( auto it = m_pBoundShaders.begin(); it != m_pBoundShaders.end(); ++it ) + { + (*it)->BindResources( pResourceMapping, Flags ); + } + } + + + SHADER_TYPE GetShaderTypeFromIndex( Int32 Index ) + { + return static_cast<SHADER_TYPE>(1 << Index); + } + + Int32 GetShaderTypeIndex( SHADER_TYPE Type ) + { + auto ShaderIndex = 0; + switch( Type ) + { + case SHADER_TYPE_UNKNOWN: ShaderIndex = -1; break; + case SHADER_TYPE_VERTEX: ShaderIndex = 0; break; + case SHADER_TYPE_PIXEL: ShaderIndex = 1; break; + case SHADER_TYPE_GEOMETRY:ShaderIndex = 2; break; + case SHADER_TYPE_HULL: ShaderIndex = 3; break; + case SHADER_TYPE_DOMAIN: ShaderIndex = 4; break; + case SHADER_TYPE_COMPUTE: ShaderIndex = 5; break; + default: UNEXPECTED( "Unexpected shader type (", Type, ")" ); ShaderIndex = -1; + } + VERIFY( Type == GetShaderTypeFromIndex(ShaderIndex), "Incorrect shader type index" ); + return ShaderIndex; + } + + const ID3D11Buffer* GetD3D11Resource( const ShaderD3D11Impl::BoundCB &CB ) { return CB.pd3d11Buff; } + const ID3D11SamplerState* GetD3D11Resource( const ShaderD3D11Impl::BoundSampler &Sampler ){ return Sampler.pd3d11Sampler; } + const ID3D11ShaderResourceView* GetD3D11Resource( const ShaderD3D11Impl::BoundSRV &SRV ) { return SRV.pd3d11View; } + const ID3D11UnorderedAccessView* GetD3D11Resource( const ShaderD3D11Impl::BoundUAV &UAV ) { return UAV.pd3d11View; } + + /// This helper template function facilitates binding different D3D11 resources to the device context + + /// \tparam TD3D11ResourceType - Type of D3D11 resource being bound (ID3D11ShaderResourceView, + /// ID3D11UnorderedAccessView, ID3D11Buffer or ID3D11SamplerState). + /// \tparam TBoundResourceType - Type of the struct describing resources associated with the + /// bound entity (ShaderD3D11Impl::BoundCB, ShaderD3D11Impl::BoundSRV, etc.) + /// \tparam TGetResourcesMethod - Type of the method that is used to get the bound resources array from + /// the shader (such as &ShaderD3D11Impl::GetBoundCBs). + /// \tparam TUnbindProc - Type of the procedure that unbinds the resource from the context + /// (for instance, if resource is set as SRV, it must be unbound from UAV slots) + /// \tparam TD3D11ResourceSetMethod - Type of the method that bounds the new resources to the D3D11 + /// device context + /// \param pShader - Pointer to the shader whose resources are to be bound + /// \param BoundResourcesArr - Pointer to the array of structures describing currently bound + /// shader resources, for each shader stage + /// \param BoundD3D11ResourcesArr - Pointer to the array of currently bound D3D11 + /// shader resources, for each shader stage + /// \param GetResources - Pointer to the method to get array of bound shader resources from the shader + /// \param UnbindProc - Function to perform required unbind steps + /// \param D3D11ResourceSetMethod - Function to set the new D3D11 resources to the D3D11 device context + template<typename TD3D11ResourceType, + typename TBoundResourceType, + typename TGetResourcesMethod, + typename TUnbindProc, + typename TD3D11ResourceSetMethod> + void UpdateBoundResources(ShaderD3D11Impl *pShader, + std::vector<TBoundResourceType> BoundResourcesArr[], + std::vector<TD3D11ResourceType*> BoundD3D11ResourcesArr[], + TGetResourcesMethod GetResources, + TUnbindProc UnbindProc, + TD3D11ResourceSetMethod D3D11ResourceSetMethod) + { + const auto &NewResources = (pShader->*GetResources)(); + auto NumNewResources = NewResources.size(); + if( NumNewResources == 0 ) + return; + + auto ShaderType = pShader->GetDesc().ShaderType; + auto ShaderInd = GetShaderTypeIndex(ShaderType); + // Get currently bound resources for the shader type + auto &BoundResources = BoundResourcesArr [ShaderInd]; + auto &BoundD3D11Resources = BoundD3D11ResourcesArr[ShaderInd]; + + VERIFY(BoundD3D11Resources.size() == BoundResources.size(), "Inconsistent array sizes") + if( NumNewResources > BoundD3D11Resources.size() ) + BoundD3D11Resources.resize(NumNewResources); + if( NumNewResources > BoundResources.size() ) + BoundResources.resize(NumNewResources); + + // Compute the minimum and the maximum slot numbers of updated D3D11 resources + Int32 MinSlot = std::numeric_limits<Int32>::max(); + Int32 MaxSlot = std::numeric_limits<Int32>::min(); + for( Int32 iSlot = 0; iSlot < static_cast<Int32>(NumNewResources); ++iSlot ) + { + const auto& pNewRes = NewResources [iSlot]; + const auto& pNewD3D11Res = GetD3D11Resource(pNewRes); + if( pNewD3D11Res != nullptr && pNewD3D11Res != BoundD3D11Resources[iSlot] ) + { + // Perform the required steps to unbind the resource + UnbindProc( pNewRes ); + + MinSlot = std::min( MinSlot, iSlot ); + MaxSlot = std::max( MaxSlot, iSlot ); + BoundD3D11Resources[iSlot] = const_cast<TD3D11ResourceType*>(pNewD3D11Res); + BoundResources[iSlot] = pNewRes; + } + } + + if( MaxSlot >= MinSlot ) + { + D3D11ResourceSetMethod(ShaderInd, MinSlot, MaxSlot - MinSlot + 1, &BoundD3D11Resources[MinSlot]); + } + + // Verify that the resource array and the D3D11 resource array are consistent + dbgVerifyResourceArrays( BoundResources, BoundD3D11Resources, pShader ); + } + + /// Template function that facilitates binding D3D11 SRVs, CBs and samplers to the device context + + /// \tparam TD3D11ResourceType - Type of D3D11 resource being bound (ID3D11ShaderResourceView, + /// ID3D11Buffer or ID3D11SamplerState). + /// \tparam TBoundResourceType - Type of the struct describing resources associated with the + /// bound entity (ShaderD3D11Impl::BoundCB, ShaderD3D11Impl::BoundSRV, etc.) + /// \tparam TGetResourcesMethod - Type of the method that is used to get the bound resources array from + /// the shader (such as &ShaderD3D11Impl::GetBoundCBs). + /// \tparam TUnbindProc - Type of the procedure that unbinds the resource from the context + /// (for instance, if resource is set as SRV, it must be unbound from UAV slots) + /// \tparam TSetD3D11Resource - Type of the D3D11 device context method used to set the + /// resource (such as &ID3D11DeviceContext::SetShaderResources) + /// \param pShader - Pointer to the shader whose resources are to be bound + /// \param BoundResourcesArr - Pointer to the array of structures describing currently bound + /// shader resources, for each shader stage + /// \param BoundD3D11ResourcesArr - Pointer to the array of currently bound D3D11 + /// shader resources, for each shader stage + /// \param GetResources - Pointer to the method to get array of bound shader resources from the shader + /// \param UnbindProc - Function to perform required unbind steps + /// \param SetD3D11ResourcesArr - Pointer to the array of device context methods used + /// to set the resource, for every shader stage + /// \param pd3d11DeviceCtx - Device context + template<typename TD3D11ResourceType, + typename TBoundResourceType, + typename TGetResourcesMethod, + typename TUnbindProc, + typename TSetD3D11Resource> + void UpdateBoundResources(ShaderD3D11Impl *pShader, + std::vector<TBoundResourceType> BoundResourcesArr[], + std::vector<TD3D11ResourceType*> BoundD3D11ResourcesArr[], + TGetResourcesMethod GetResources, + TUnbindProc UnbindProc, + TSetD3D11Resource SetD3D11ResourcesArr[], + ID3D11DeviceContext *pd3d11DeviceCtx) + { + UpdateBoundResources(pShader, BoundResourcesArr, BoundD3D11ResourcesArr, + GetResources, UnbindProc, + [&](Int32 ShaderInd, UINT MinSlot, UINT NumSlots, TD3D11ResourceType** ppD3D11Resources) + { + auto SetD3D11Resources = SetD3D11ResourcesArr[ShaderInd]; + VERIFY(SetD3D11Resources, "Set D3D11 resource function pointer is null."); + if( SetD3D11Resources ) + { + (pd3d11DeviceCtx->*SetD3D11Resources)(MinSlot, NumSlots, ppD3D11Resources); + } + } + ); + } + +/// Helper macro used to create an array of device context methods to +/// set particular resource for every shader stage +#define DEFINE_D3D11CTX_FUNC_POINTERS(ArrayName, FuncName) \ + typedef decltype (&ID3D11DeviceContext::VS##FuncName) T##FuncName##Type; \ + static const T##FuncName##Type ArrayName[] = \ + { \ + &ID3D11DeviceContext::VS##FuncName, \ + &ID3D11DeviceContext::PS##FuncName, \ + &ID3D11DeviceContext::GS##FuncName, \ + &ID3D11DeviceContext::HS##FuncName, \ + &ID3D11DeviceContext::DS##FuncName, \ + &ID3D11DeviceContext::CS##FuncName \ + }; + + DEFINE_D3D11CTX_FUNC_POINTERS(SetCBMethods, SetConstantBuffers) + DEFINE_D3D11CTX_FUNC_POINTERS(SetSRVMethods, SetShaderResources) + DEFINE_D3D11CTX_FUNC_POINTERS(SetSamplerMethods, SetSamplers) + + typedef decltype (&ID3D11DeviceContext::CSSetUnorderedAccessViews) TSetUnorderedAccessViewsType; + static const TSetUnorderedAccessViewsType SetUAVMethods[] = + { + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + &ID3D11DeviceContext::CSSetUnorderedAccessViews + }; + + void DeviceContextD3D11Impl::SetD3DConstantBuffers( ShaderD3D11Impl *pShader ) + { + UpdateBoundResources(pShader, m_BoundCBs, m_BoundD3D11CBs, + &ShaderD3D11Impl::GetBoundCBs, + [&](const ShaderD3D11Impl::BoundCB &BoundCB) + { + auto *pResource = const_cast<IDeviceObject *>(BoundCB.pBuff.RawPtr()); + RefCntAutoPtr<IBuffer> pBuff; + pResource->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>( static_cast<IBuffer**>(&pBuff) ) ); + if( pBuff ) + { + if( pBuff->GetDesc().BindFlags & BIND_UNORDERED_ACCESS ) + UnbindResourceFromUAV( pBuff ); + } + else + { + UNEXPECTED( "Resource \"", pResource->GetDesc().Name, "\" is expected to be a buffer" ) + } + }, + SetCBMethods, + m_pd3d11DeviceContext ); + dbgVerifyContextCBs(pShader->GetDesc().ShaderType); + } + + void DeviceContextD3D11Impl::SetD3DSRVs( ShaderD3D11Impl *pShader ) + { + UpdateBoundResources(pShader, m_BoundSRVs, m_BoundD3D11SRVs, + &ShaderD3D11Impl::GetBoundSRVs, + [&](const ShaderD3D11Impl::BoundSRV &BoundSRV) + { + auto *pResource = const_cast<IDeviceObject *>(BoundSRV.pResource.RawPtr()); + RefCntAutoPtr<ITexture> pTexture; + pResource->QueryInterface( IID_Texture, reinterpret_cast<IObject**>( static_cast<ITexture**>(&pTexture) ) ); + if( pTexture ) + { + auto BindFlags = pTexture->GetDesc().BindFlags; + if( BindFlags & BIND_UNORDERED_ACCESS ) + UnbindResourceFromUAV(pTexture); + if( BindFlags & BIND_RENDER_TARGET ) + UnbindTextureFromRenderTarget(pTexture); + if( BindFlags & BIND_DEPTH_STENCIL ) + UnbindTextureFromDepthStencil(pTexture); + } + else + { + RefCntAutoPtr<IBuffer> pBuffer; + pResource->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(static_cast<IBuffer**>(&pBuffer)) ); + if( pBuffer ) + { + if( pBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS ) + UnbindResourceFromUAV( pBuffer ); + } + else + { + UNEXPECTED( "Resource \"", pResource->GetDesc().Name, "\" is expected to be a texture or a buffer." ) + } + } + }, + SetSRVMethods, + m_pd3d11DeviceContext ); + dbgVerifyContextSRVs(pShader->GetDesc().ShaderType); + } + + void DeviceContextD3D11Impl::SetD3DSamplers( ShaderD3D11Impl *pShader ) + { + UpdateBoundResources(pShader, m_BoundSamplers, m_BoundD3D11Samplers, + &ShaderD3D11Impl::GetBoundSamplers, + [](const ShaderD3D11Impl::BoundSampler& ){}, // Do nothing + SetSamplerMethods, + m_pd3d11DeviceContext ); + dbgVerifyContextSamplers(pShader->GetDesc().ShaderType); + } + + void DeviceContextD3D11Impl::SetD3DUAVs( ShaderD3D11Impl *pShader ) + { + UpdateBoundResources(pShader, m_BoundUAVs, m_BoundD3D11UAVs, + &ShaderD3D11Impl::GetBoundUAVs, + [&](const ShaderD3D11Impl::BoundUAV& BoundUAV) + { + auto *pResource = const_cast<IDeviceObject *>(BoundUAV.pResource.RawPtr()); + RefCntAutoPtr<ITexture> pTexture; + pResource->QueryInterface( IID_Texture, reinterpret_cast<IObject**>( static_cast<ITexture**>(&pTexture) ) ); + if( pTexture ) + { + // It is unlikely the texture is not used for input, so do not + // check the bind flags + UnbindTextureFromInput( pTexture ); + } + else + { + RefCntAutoPtr<IBuffer> pBuffer; + pResource->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(static_cast<IBuffer**>(&pBuffer)) ); + if( pBuffer ) + { + // It is unlikely the buffer is not used for input, so do not + // check the bind flags + UnbindBufferFromInput( pBuffer ); + } + else + { + UNEXPECTED( "Resource \"", pResource->GetDesc().Name, "\" is expected to be a texture or a buffer." ) + } + } + }, + [&](Int32 ShaderInd, UINT MinUAVSlot, UINT NumUAVSlots, ID3D11UnorderedAccessView** ppUAVs) + { + switch( ShaderInd ) + { + case 0: // SHADER_TYPE_PIXEL: + UNSUPPORTED( "UAVs are not currently implemented in pixel shader" ); + /// \TODO: need to keep track of bound RTVs and provide the render targets here. + /// Also, we need to unbind UAVs appropriatelly. + /// Maybe deffer actual render target binding to the Draw call()? + m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews( 0, nullptr, nullptr, MinUAVSlot, NumUAVSlots, ppUAVs, nullptr ); + break; + + case 1: //SHADER_TYPE_VERTEX: + case 2: //SHADER_TYPE_GEOMETRY: + case 3: //SHADER_TYPE_DOMAIN: + case 4: //SHADER_TYPE_HULL: + UNSUPPORTED( "UAVs are not currently supported in this type of shader" ); + break; + + case 5: //SHADER_TYPE_COMPUTE: + m_pd3d11DeviceContext->CSSetUnorderedAccessViews( MinUAVSlot, NumUAVSlots, ppUAVs, nullptr ); + break; + + default: UNEXPECTED( "Unknown shader type" ); + } + } + ); + dbgVerifyContextUAVs(pShader->GetDesc().ShaderType); + } + + template<typename TD3D11ShaderType, typename TBindShaderMethdType> + void DeviceContextD3D11Impl :: SetD3D11ShaderHelper(Uint32 BoundShaderFlags, + ShaderD3D11Impl* NewShaders[], + SHADER_TYPE ShaderType, + TBindShaderMethdType BindShaderMethod) + { + auto ShaderTypeInd = GetShaderTypeIndex( ShaderType ); + auto &BoundD3D11Shader = m_BoundD3DShaders[ShaderTypeInd]; + auto *pShaderD3D11 = NewShaders[ShaderTypeInd]; + if( BoundShaderFlags & ShaderType ) + { + VERIFY( pShaderD3D11 != nullptr, "Shader is null" ); + VERIFY( pShaderD3D11->GetDesc().ShaderType == ShaderType, "Unexpected shader type" ); + if( BoundD3D11Shader != pShaderD3D11->m_pShader ) + { + BoundD3D11Shader = pShaderD3D11->m_pShader; + RefCntAutoPtr<TD3D11ShaderType> pd3d11Shader; + pShaderD3D11->m_pShader->QueryInterface(__uuidof(TD3D11ShaderType), reinterpret_cast<void**>( static_cast<TD3D11ShaderType**>(&pd3d11Shader) ) ); + (m_pd3d11DeviceContext->*BindShaderMethod)(pd3d11Shader, nullptr, 0); + } + } + else + { + if( BoundD3D11Shader != nullptr ) + { + BoundD3D11Shader = nullptr; + (m_pd3d11DeviceContext->*BindShaderMethod)(nullptr, nullptr, 0); + } + } + } + + void DeviceContextD3D11Impl :: SetD3DShadersAndResources() + { + Uint32 BoundShaderFlags = 0; + // Set shaders + ShaderD3D11Impl* NewShaders[NumShaderTypes] = {}; + for( auto it = m_pBoundShaders.begin(); it != m_pBoundShaders.end(); ++it ) + { + auto *pCurrShader = it->RawPtr(); + if( pCurrShader ) + { + auto ShaderType = pCurrShader->GetDesc().ShaderType; + auto *pShaderD3D11 = static_cast<ShaderD3D11Impl*>(pCurrShader); + auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + NewShaders[ShaderTypeInd] = pShaderD3D11; + + if( BoundShaderFlags & ShaderType ) + LOG_ERROR_MESSAGE( "More than one shader of type ", GetShaderTypeLiteralName(ShaderType), " is bound to the context" ) + BoundShaderFlags |= ShaderType; + +#ifdef VERIFY_SHADER_BINDINGS + pShaderD3D11->dbgVerifyBindings(); +#endif + + // Set D3D11 shader resources + SetD3DConstantBuffers ( pShaderD3D11 ); + SetD3DSRVs ( pShaderD3D11 ); + SetD3DSamplers ( pShaderD3D11 ); + SetD3DUAVs ( pShaderD3D11 ); + } + } + + // There is no need to unbind the compute shader from the context + //if( BoundShaderFlags & SHADER_TYPE_COMPUTE ) + //{ + // LOG_ERROR_MESSAGE( "Bound compute shader will be ignored by the draw command" ) + // BoundShaderFlags &= ~SHADER_TYPE_COMPUTE; + //} + +#define SET_SHADER(NAME, Name, N) SetD3D11ShaderHelper<ID3D11##Name##Shader>(BoundShaderFlags, NewShaders, SHADER_TYPE_##NAME, &ID3D11DeviceContext::N##SSetShader ) + + // These shaders which are not set will be unbound from the D3D11 device context + SET_SHADER( VERTEX, Vertex, V ); + SET_SHADER( PIXEL, Pixel, P ); + SET_SHADER( GEOMETRY, Geometry, G ); + SET_SHADER( DOMAIN, Domain, D ); + SET_SHADER( HULL, Hull, H ); + // There is no need to unbind the compute shader from the context + //SET_SHADER( COMPUTE, Compute, C ); + } + + void DeviceContextD3D11Impl::SetD3DIndexBuffer(VALUE_TYPE IndexType) + { + if( !m_pIndexBuffer ) + { + LOG_ERROR_MESSAGE( "Index buffer is not set up for indexed draw command" ); + return; + } + BufferD3D11Impl *pBuffD3D11 = static_cast<BufferD3D11Impl *>(m_pIndexBuffer.RawPtr()); + DXGI_FORMAT D3D11IndexFmt = DXGI_FORMAT_UNKNOWN; + if( IndexType == VT_UINT32 ) + D3D11IndexFmt = DXGI_FORMAT_R32_UINT; + else if( IndexType == VT_UINT16 ) + D3D11IndexFmt = DXGI_FORMAT_R16_UINT; + else + { + LOG_ERROR_MESSAGE( "Unsupported index format. Only R16_UINT and R32_UINT are allowed." ); + return; + } + if( m_pIndexBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS ) + UnbindResourceFromUAV(m_pIndexBuffer); + + if( m_BoundD3D11IndexBuffer != pBuffD3D11->m_pd3d11Buffer || + m_BoundD3D11IndexFmt != D3D11IndexFmt || + m_BoundD3D11IndexDataStartOffset != m_IndexDataStartOffset ) + { + m_BoundD3D11IndexBuffer = pBuffD3D11->m_pd3d11Buffer; + m_BoundD3D11IndexFmt = D3D11IndexFmt; + m_BoundD3D11IndexDataStartOffset = m_IndexDataStartOffset; + m_pd3d11DeviceContext->IASetIndexBuffer( pBuffD3D11->m_pd3d11Buffer, D3D11IndexFmt, m_IndexDataStartOffset ); + } + } + + void DeviceContextD3D11Impl::SetD3DVertexBuffers() + { + auto &VertexDescSP = m_pVertexDesc; + if( !VertexDescSP ) + { + // There might be no vertex description if, for instance, full screen quad + // is rendered + m_pd3d11DeviceContext->IASetInputLayout( nullptr ); + return; + } + auto* pVertexDescD3D11 = static_cast<VertexDescD3D11Impl *>(VertexDescSP.RawPtr()); + m_pd3d11DeviceContext->IASetInputLayout( pVertexDescD3D11->m_pd3d11InputLayout ); + + ID3D11Buffer *ppD3D11Buffers[MaxBufferSlots] = { nullptr }; + UINT Strides[MaxBufferSlots] = { 0 }; + UINT Offsets[MaxBufferSlots] = { 0 }; + UINT NumBoundBuffers = static_cast<UINT>(m_VertexStreams.size()); + VERIFY( NumBoundBuffers <= MaxBufferSlots, "Too many buffers are being set" ); + NumBoundBuffers = std::min( NumBoundBuffers, static_cast<UINT>(MaxBufferSlots) ); + const auto *TightStrides = VertexDescSP->GetTightStrides(); + for( UINT Buff = 0; Buff < NumBoundBuffers; ++Buff ) + { + auto &CurrStream = m_VertexStreams[Buff]; + VERIFY( CurrStream.pBuffer, "Attempting to bind a null buffer for rendering" ); + ppD3D11Buffers[Buff] = static_cast<BufferD3D11Impl*>(CurrStream.pBuffer.RawPtr())->m_pd3d11Buffer; + Strides[Buff] = CurrStream.Stride ? CurrStream.Stride : TightStrides[Buff]; + Offsets[Buff] = CurrStream.Offset; + if(CurrStream.pBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS) + UnbindResourceFromUAV(CurrStream.pBuffer); + } + + UINT NumBuffersToSet = NumBoundBuffers; + bool BindVBs = false; + if( NumBoundBuffers != m_BoundD3D11VertexBuffers.size() ) + { + // If number of currently bound d3d11 buffers is larger than NumBuffersToSet, the + // unused buffers will be unbound + NumBuffersToSet = std::max(NumBuffersToSet, static_cast<UINT>(m_BoundD3D11VertexBuffers.size()) ); + m_BoundD3D11VertexBuffers.resize(NumBoundBuffers); + m_BoundD3D11VBStrides.resize(NumBoundBuffers); + m_BoundD3D11VBOffsets.resize( NumBoundBuffers ); + BindVBs = true; + } + + for( UINT Slot = 0; Slot < NumBoundBuffers; ++Slot ) + { + if( m_BoundD3D11VertexBuffers[Slot] != ppD3D11Buffers[Slot] || + m_BoundD3D11VBStrides[Slot] != Strides[Slot] || + m_BoundD3D11VBOffsets[Slot] != Offsets[Slot] ) + { + BindVBs = true; + + m_BoundD3D11VertexBuffers[Slot] = ppD3D11Buffers[Slot]; + m_BoundD3D11VBStrides[Slot] = Strides[Slot]; + m_BoundD3D11VBOffsets[Slot] = Offsets[Slot]; + } + } + + if( BindVBs ) + { + m_pd3d11DeviceContext->IASetVertexBuffers( 0, NumBuffersToSet, ppD3D11Buffers, Strides, Offsets ); + } + } + + void DeviceContextD3D11Impl::Draw( DrawAttribs &DrawAttribs ) + { + m_LastDrawAttribs = DrawAttribs; + + SetD3DShadersAndResources(); + + SetD3DVertexBuffers(); + + if( DrawAttribs.IsIndexed ) + { + SetD3DIndexBuffer(DrawAttribs.IndexType); + } + + // Verify bindings after all resources are set + dbgVerifyContextSRVs(); + dbgVerifyContextUAVs(); + dbgVerifyContextSamplers(); + dbgVerifyContextCBs(); + dbgVerifyVertexBuffers(); + dbgVerifyIndexBuffer(); + dbgVerifyShaders(); + + auto D3D11Topology = TopologyToDX11Topology( DrawAttribs.Topology ); + m_pd3d11DeviceContext->IASetPrimitiveTopology( D3D11Topology ); + + if( DrawAttribs.IsIndirect ) + { + VERIFY( DrawAttribs.pIndirectDrawAttribs, "Indirect draw command attributes buffer is not set" ); + auto *pBufferD3D11 = static_cast<BufferD3D11Impl*>(DrawAttribs.pIndirectDrawAttribs); + ID3D11Buffer *pd3d11ArgsBuff = pBufferD3D11 ? pBufferD3D11->m_pd3d11Buffer.RawPtr() : nullptr; + if( DrawAttribs.IsIndexed ) + m_pd3d11DeviceContext->DrawIndexedInstancedIndirect( pd3d11ArgsBuff, DrawAttribs.IndirectDrawArgsOffset ); + else + m_pd3d11DeviceContext->DrawInstancedIndirect( pd3d11ArgsBuff, DrawAttribs.IndirectDrawArgsOffset ); + } + else + { + if( DrawAttribs.NumInstances > 1 ) + { + if( DrawAttribs.IsIndexed ) + m_pd3d11DeviceContext->DrawIndexedInstanced( DrawAttribs.NumIndices, DrawAttribs.NumInstances, DrawAttribs.FirstIndexLocation, DrawAttribs.BaseVertex, DrawAttribs.FirstInstanceLocation ); + else + m_pd3d11DeviceContext->DrawInstanced( DrawAttribs.NumVertices, DrawAttribs.NumInstances, DrawAttribs.StartVertexLocation, DrawAttribs.FirstInstanceLocation ); + } + else + { + if( DrawAttribs.IsIndexed ) + m_pd3d11DeviceContext->DrawIndexed( DrawAttribs.NumIndices, DrawAttribs.FirstIndexLocation, DrawAttribs.BaseVertex ); + else + m_pd3d11DeviceContext->Draw( DrawAttribs.NumVertices, DrawAttribs.StartVertexLocation ); + } + } + } + + void DeviceContextD3D11Impl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs ) + { + bool bCSBound = false; + ShaderD3D11Impl* NewShaders[NumShaderTypes] = {}; + for( auto it = m_pBoundShaders.begin(); it != m_pBoundShaders.end() && !bCSBound; ++it ) + { + auto *pCurrShader = it->RawPtr(); + if( pCurrShader && pCurrShader->GetDesc().ShaderType == SHADER_TYPE_COMPUTE ) + { + bCSBound = true; + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>(pCurrShader); + NewShaders[GetShaderTypeIndex(SHADER_TYPE_COMPUTE)] = pShaderD3D11; + SetD3D11ShaderHelper<ID3D11ComputeShader>( SHADER_TYPE_COMPUTE, NewShaders, SHADER_TYPE_COMPUTE, &ID3D11DeviceContext::CSSetShader ); + +#ifdef VERIFY_SHADER_BINDINGS + pShaderD3D11->dbgVerifyBindings(); +#endif + + // Set requried shader resources + SetD3DConstantBuffers ( pShaderD3D11 ); + SetD3DSRVs ( pShaderD3D11 ); + SetD3DSamplers ( pShaderD3D11 ); + SetD3DUAVs ( pShaderD3D11 ); + + break; + } + } + + if( !bCSBound ) + { + LOG_ERROR_MESSAGE( "Compute shader is not bound to the pipeline" ); + return; + } + + // Verify bindings + dbgVerifyContextSRVs(); + dbgVerifyContextUAVs(); + dbgVerifyContextSamplers(); + dbgVerifyContextCBs(); + dbgVerifyShaders(); + + if( DispatchAttrs.pIndirectDispatchAttribs ) + { + CHECK_DYNAMIC_TYPE( BufferD3D11Impl, DispatchAttrs.pIndirectDispatchAttribs ); + auto *pd3d11Buff = static_cast<BufferD3D11Impl*>(DispatchAttrs.pIndirectDispatchAttribs)->GetD3D11Buffer(); + m_pd3d11DeviceContext->DispatchIndirect( pd3d11Buff, DispatchAttrs.DispatchArgsByteOffset ); + } + else + m_pd3d11DeviceContext->Dispatch( DispatchAttrs.ThreadGroupCountX, DispatchAttrs.ThreadGroupCountY, DispatchAttrs.ThreadGroupCountZ ); + } + + void DeviceContextD3D11Impl::ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil ) + { + ID3D11DepthStencilView *pd3d11DSV = nullptr; + if( pView != nullptr ) + { + const auto& ViewDesc = pView->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); + CHECK_DYNAMIC_TYPE( TextureViewD3D11Impl, pView ); + auto *pViewD3D11 = static_cast<TextureViewD3D11Impl*>(pView); + pd3d11DSV = static_cast<ID3D11DepthStencilView *>(pViewD3D11->GetD3D11View()); + } + else + { + pd3d11DSV = ValidatedCast<SwapChainD3D11Impl>(m_pSwapChain.RawPtr())->GetDSV(); + } + UINT32 d3d11ClearFlags = 0; + if( ClearFlags & CLEAR_DEPTH_FLAG ) d3d11ClearFlags |= D3D11_CLEAR_DEPTH; + if( ClearFlags & CLEAR_STENCIL_FLAG ) d3d11ClearFlags |= D3D11_CLEAR_STENCIL; + // The full extent of the resource view is always cleared. + // Viewport and scissor settings are not applied. + m_pd3d11DeviceContext->ClearDepthStencilView( pd3d11DSV, d3d11ClearFlags, fDepth, Stencil ); + } + + void DeviceContextD3D11Impl::ClearRenderTarget( ITextureView *pView, const float *RGBA ) + { + ID3D11RenderTargetView *pd3d11RTV = nullptr; + if( pView != nullptr ) + { + const auto& ViewDesc = pView->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); + CHECK_DYNAMIC_TYPE( TextureViewD3D11Impl, pView ); + auto *pViewD3D11 = static_cast<TextureViewD3D11Impl*>(pView); + pd3d11RTV = static_cast<ID3D11RenderTargetView*>(pViewD3D11->GetD3D11View()); + } + else + { + pd3d11RTV = ValidatedCast<SwapChainD3D11Impl>(m_pSwapChain.RawPtr())->GetRTV(); + } + + static const float Zero[4] = { 0.f, 0.f, 0.f, 0.f }; + if( RGBA == nullptr ) + RGBA = Zero; + + // The full extent of the resource view is always cleared. + // Viewport and scissor settings are not applied. + m_pd3d11DeviceContext->ClearRenderTargetView( pd3d11RTV, RGBA ); + } + + void DeviceContextD3D11Impl::Flush() + { + m_pd3d11DeviceContext->Flush(); + } + + void DeviceContextD3D11Impl::SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) + { + TDeviceContextBase::SetVertexBuffers( StartSlot, NumBuffersSet, ppBuffers, pStrides, pOffsets, Flags ); + } + + void DeviceContextD3D11Impl::ClearState() + { + TDeviceContextBase::ClearState(); + + } + + void DeviceContextD3D11Impl::SetVertexDescription( IVertexDescription *pVertexDesc ) + { + TDeviceContextBase::SetVertexDescription( pVertexDesc ); + } + + void DeviceContextD3D11Impl::SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) + { + TDeviceContextBase::SetIndexBuffer( pIndexBuffer, ByteOffset ); + } + + void DeviceContextD3D11Impl::SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef ) + { + if( TDeviceContextBase::SetDepthStencilState( pDepthStencilState, StencilRef ) ) + { + CHECK_DYNAMIC_TYPE( DSStateD3D11Impl, pDepthStencilState ); + auto *pDSSD3D11 = static_cast<DSStateD3D11Impl*>(pDepthStencilState); + auto *pd3d11DSS = pDSSD3D11->GetD3D11DepthStencilState(); + m_pd3d11DeviceContext->OMSetDepthStencilState( pd3d11DSS, StencilRef ); + } + } + + void DeviceContextD3D11Impl::SetRasterizerState( IRasterizerState *pRasterizerState ) + { + if( TDeviceContextBase::SetRasterizerState( pRasterizerState ) ) + { + CHECK_DYNAMIC_TYPE( RasterizerStateD3D11Impl, pRasterizerState ); + auto *pRSD3D11 = static_cast<RasterizerStateD3D11Impl*>(pRasterizerState); + auto *pd3d11RS = pRSD3D11->GetD3D11RasterizerState(); + m_pd3d11DeviceContext->RSSetState( pd3d11RS ); + } + } + + void DeviceContextD3D11Impl::SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask ) + { + if( TDeviceContextBase::SetBlendState( pBS, pBlendFactors, SampleMask ) ) + { + CHECK_DYNAMIC_TYPE( BlendStateD3D11Impl, pBS ); + auto *pBSD3D11 = static_cast<BlendStateD3D11Impl*>(pBS); + auto *pd3d11BS = pBSD3D11->GetD3D11BlendState(); + m_pd3d11DeviceContext->OMSetBlendState( pd3d11BS, m_BlendFactors, SampleMask ); + } + } + + void DeviceContextD3D11Impl::SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight ) + { + const Uint32 MaxViewports = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + VERIFY( NumViewports < MaxViewports, "Too many viewports are being set" ); + NumViewports = std::min( NumViewports, MaxViewports ); + + TDeviceContextBase::SetViewports( NumViewports, pViewports, RTWidth, RTHeight ); + + D3D11_VIEWPORT d3d11Viewports[MaxViewports]; + VERIFY( NumViewports == m_Viewports.size(), "Unexpected number of viewports" ); + for( Uint32 vp = 0; vp < NumViewports; ++vp ) + { + d3d11Viewports[vp].TopLeftX = m_Viewports[vp].TopLeftX; + d3d11Viewports[vp].TopLeftY = m_Viewports[vp].TopLeftY; + d3d11Viewports[vp].Width = m_Viewports[vp].Width; + d3d11Viewports[vp].Height = m_Viewports[vp].Height; + d3d11Viewports[vp].MinDepth = m_Viewports[vp].MinDepth; + d3d11Viewports[vp].MaxDepth = m_Viewports[vp].MaxDepth; + } + // All viewports must be set atomically as one operation. + // Any viewports not defined by the call are disabled. + m_pd3d11DeviceContext->RSSetViewports( NumViewports, d3d11Viewports ); + } + + void DeviceContextD3D11Impl::SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight ) + { + const Uint32 MaxScissorRects = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + VERIFY( NumRects < MaxScissorRects, "Too many scissor rects are being set" ); + NumRects = std::min( NumRects, MaxScissorRects ); + + TDeviceContextBase::SetScissorRects(NumRects, pRects, RTWidth, RTHeight); + + D3D11_RECT d3d11ScissorRects[MaxScissorRects]; + VERIFY( NumRects == m_ScissorRects.size(), "Unexpected number of scissor rects" ); + for( Uint32 sr = 0; sr < NumRects; ++sr ) + { + d3d11ScissorRects[sr].left = m_ScissorRects[sr].left; + d3d11ScissorRects[sr].top = m_ScissorRects[sr].top; + d3d11ScissorRects[sr].right = m_ScissorRects[sr].right; + d3d11ScissorRects[sr].bottom = m_ScissorRects[sr].bottom; + } + + // All scissor rects must be set atomically as one operation. + // Any scissor rects not defined by the call are disabled. + m_pd3d11DeviceContext->RSSetScissorRects( NumRects, d3d11ScissorRects ); + } + + void DeviceContextD3D11Impl::RebindRenderTargets() + { + const Uint32 MaxD3D11RTs = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; + Uint32 NumRenderTargets = static_cast<Uint32>( m_pBoundRenderTargets.size() ); + VERIFY( NumRenderTargets <= MaxD3D11RTs, "D3D11 only allows 8 simultaneous render targets" ); + NumRenderTargets = std::min( MaxD3D11RTs, NumRenderTargets ); + + ID3D11RenderTargetView *pd3d11RTs[MaxD3D11RTs] = {}; + ID3D11DepthStencilView *pd3d11DSV = nullptr; + + auto *pDepthStencil = m_pBoundDepthStencil.RawPtr(); + if( NumRenderTargets == 0 && pDepthStencil == nullptr ) + { + NumRenderTargets = 1; + auto *pSwapChainD3D11 = ValidatedCast<SwapChainD3D11Impl>( m_pSwapChain.RawPtr() ); + pd3d11RTs[0] = pSwapChainD3D11->GetRTV(); + pd3d11DSV = pSwapChainD3D11->GetDSV(); + } + else + { + for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + { + auto *pView = m_pBoundRenderTargets[rt].RawPtr(); + if( pView ) + { + auto *pViewD3D11 = static_cast<TextureViewD3D11Impl*>(pView); + pd3d11RTs[rt] = static_cast<ID3D11RenderTargetView*>(pViewD3D11->GetD3D11View()); + } + else + pd3d11RTs[rt] = nullptr; + } + + if( pDepthStencil != nullptr ) + { + auto *pViewD3D11 = static_cast<TextureViewD3D11Impl*>(pDepthStencil); + pd3d11DSV = static_cast<ID3D11DepthStencilView*>(pViewD3D11->GetD3D11View()); + } + } + + m_pd3d11DeviceContext->OMSetRenderTargets(NumRenderTargets, pd3d11RTs, pd3d11DSV); + } + + void UnbindView( ID3D11DeviceContext *pContext, TSetShaderResourcesType SetSRVMethod, UINT Slot ) + { + ID3D11ShaderResourceView *ppNullView[] = { nullptr }; + (pContext->*SetSRVMethod)(Slot, 1, ppNullView); + } + + void UnbindView( ID3D11DeviceContext *pContext, TSetUnorderedAccessViewsType SetUAVMethod, UINT Slot ) + { + ID3D11UnorderedAccessView *ppNullView[] = { nullptr }; + (pContext->*SetUAVMethod)(Slot, 1, ppNullView, nullptr); + } + + /// \tparam TBoundResourceType - Type of the struct describing resources associated with the + /// bound entity (ShaderD3D11Impl::BoundCB, ShaderD3D11Impl::BoundSRV, etc.) + /// \tparam TD3D11ResourceType - Type of the D3D11 resource (ID3D11ShaderResourceView or ID3D11UnorderedAccessView) + /// \tparam TSetD3D11View - Type of the D3D11 device context method used to set the D3D11 view + /// \param BoundResourcesArr - Pointer to the array of strong references to currently bound + /// shader resources, for each shader stage + /// \param BoundD3D11ResourcesArr - Pointer to the array of currently bound D3D11 + /// shader resources, for each shader stage + /// \param pResToUnbind - Resource to unbind + /// \param SetD3D11ViewMethods - Array of pointers to device context methods used to set the view, + /// for every shader stage + template<typename TBoundResourceType, + typename TD3D11ResourceType, + typename TSetD3D11View> + void DeviceContextD3D11Impl::UnbindResourceView(std::vector<TBoundResourceType> BoundResourcesArr[], + std::vector<TD3D11ResourceType> BoundD3D11ResourcesArr[], + IDeviceObject *pResToUnbind, + TSetD3D11View SetD3D11ViewMethods[]) + { + for( Int32 ShaderTypeInd = 0; ShaderTypeInd < NumShaderTypes; ++ShaderTypeInd ) + { + auto &BoundResources = BoundResourcesArr[ShaderTypeInd]; + auto &BoundD3D11Views = BoundD3D11ResourcesArr[ShaderTypeInd]; + VERIFY( BoundResources.size() == BoundD3D11Views.size(), "Inconsistent shader resource view array sizes" ); + for( Uint32 Slot = 0; Slot < BoundResources.size(); ++Slot ) + { + if( BoundResources[Slot].pResource == pResToUnbind ) + { + BoundResources[Slot] = TBoundResourceType(); + BoundD3D11Views[Slot] = nullptr; + + auto SetViewMethod = SetD3D11ViewMethods[ShaderTypeInd]; + UnbindView( m_pd3d11DeviceContext, SetViewMethod, Slot ); + } + } + + // Pop null resources from the end of arrays + while( BoundD3D11Views.size() > 0 && BoundD3D11Views.back() == nullptr ) + { + BoundD3D11Views.pop_back(); + VERIFY( BoundResources.back().pResource == nullptr, "Unexpected non-null resource detected" ) + VERIFY( BoundResources.back().pView == nullptr, "Unexpected non-null resource view detected" ) + VERIFY( BoundResources.back().pd3d11View == nullptr, "Unexpected non-null D3D11 resource view detected" ) + BoundResources.pop_back(); + } + VERIFY(BoundResources.size() == BoundD3D11Views.size(), "Inconsistent array size") + } + } + + void DeviceContextD3D11Impl::UnbindTextureFromInput( ITexture *pTexture ) + { + VERIFY( pTexture, "Null texture provided" ) + if( !pTexture )return; + + UnbindResourceView( m_BoundSRVs, m_BoundD3D11SRVs, pTexture, SetSRVMethods ); + } + + void DeviceContextD3D11Impl::UnbindBufferFromInput( IBuffer *pBuffer ) + { + VERIFY( pBuffer, "Null buffer provided" ) + if( !pBuffer )return; + + UnbindResourceView( m_BoundSRVs, m_BoundD3D11SRVs, pBuffer, SetSRVMethods ); + + auto BuffBindFlags = pBuffer->GetDesc().BindFlags; + + if( (BuffBindFlags & BIND_INDEX_BUFFER) && m_BoundD3D11IndexBuffer ) + { + auto pd3d11IndBuffer = ValidatedCast<BufferD3D11Impl>( pBuffer )->GetD3D11Buffer(); + if( pd3d11IndBuffer == m_BoundD3D11IndexBuffer ) + { + // Only unbind D3D11 buffer from the context! + // m_pIndexBuffer.Release(); + m_BoundD3D11IndexBuffer.Release(); + m_BoundD3D11IndexFmt = DXGI_FORMAT_UNKNOWN; + m_BoundD3D11IndexDataStartOffset = 0; + m_pd3d11DeviceContext->IASetIndexBuffer( nullptr, m_BoundD3D11IndexFmt, m_BoundD3D11IndexDataStartOffset ); + } + dbgVerifyIndexBuffer(); + } + + if( BuffBindFlags & BIND_VERTEX_BUFFER ) + { + auto pd3d11VB = ValidatedCast<BufferD3D11Impl>( pBuffer )->GetD3D11Buffer(); + for( Uint32 Slot = 0; Slot < m_BoundD3D11VertexBuffers.size(); ++Slot ) + { + auto &BoundD3D11VB = m_BoundD3D11VertexBuffers[Slot]; + if(BoundD3D11VB == pd3d11VB) + { + // Unbind only D3D11 buffer + //*VertStream = VertexStreamInfo(); + ID3D11Buffer *ppNullBuffer[] = { nullptr }; + const UINT Zero[] = { 0 }; + m_BoundD3D11VertexBuffers[Slot].Release(); + m_BoundD3D11VBStrides[Slot] = 0; + m_BoundD3D11VBOffsets[Slot] = 0; + m_pd3d11DeviceContext->IASetVertexBuffers( Slot, _countof( ppNullBuffer ), ppNullBuffer, Zero, Zero ); + } + } + dbgVerifyVertexBuffers(); + } + + if( BuffBindFlags & BIND_UNIFORM_BUFFER ) + { + for( Int32 ShaderTypeInd = 0; ShaderTypeInd < NumShaderTypes; ++ShaderTypeInd ) + { + auto &BoundCBs = m_BoundCBs[ShaderTypeInd]; + auto &BoundD3D11CBs = m_BoundD3D11CBs[ShaderTypeInd]; + VERIFY( BoundCBs.size() == BoundD3D11CBs.size(), "Inconsistent constant buffer array sizes" ); + auto NumSlots = std::min( BoundCBs.size(), BoundD3D11CBs.size() ); + for( Uint32 Slot = 0; Slot < NumSlots; ++Slot ) + { + if( BoundCBs[Slot].pBuff == pBuffer ) + { + BoundCBs[Slot] = ShaderD3D11Impl::BoundCB(); + BoundD3D11CBs[Slot] = nullptr; + auto SetCBMethod = SetCBMethods[ShaderTypeInd]; + ID3D11Buffer *ppNullBuffer[] = { nullptr }; + (m_pd3d11DeviceContext->*SetCBMethod)(Slot, 1, ppNullBuffer); + } + } + } + + dbgVerifyContextCBs(); + } + } + + void DeviceContextD3D11Impl::UnbindResourceFromUAV( IDeviceObject *pResource ) + { + VERIFY( pResource, "Null resource provided" ) + if( !pResource )return; + + UnbindResourceView( m_BoundUAVs, m_BoundD3D11UAVs, pResource, SetUAVMethods ); + } + + void DeviceContextD3D11Impl::UnbindTextureFromRenderTarget( IDeviceObject *pResource ) + { + VERIFY( pResource, "Null resource provided" ) + if( !pResource )return; + VERIFY(ValidatedCast<ITexture>( pResource ), "Resource is not a texture") + + bool bRebindRenderTargets = false; + for( auto rt = m_pBoundRenderTargets.begin(); rt != m_pBoundRenderTargets.end(); ++rt ) + { + if( auto pTexView = *rt ) + { + if( pTexView->GetTexture() == pResource ) + { + (*rt).Release(); + bRebindRenderTargets = true; + } + } + } + + if( bRebindRenderTargets ) + RebindRenderTargets(); + } + + void DeviceContextD3D11Impl::UnbindTextureFromDepthStencil(IDeviceObject *pResource) + { + VERIFY( pResource, "Null resource provided" ) + if( !pResource )return; + VERIFY(ValidatedCast<ITexture>( pResource ), "Resource is not a texture") + + if( m_pBoundDepthStencil && m_pBoundDepthStencil->GetTexture() == pResource ) + { + m_pBoundDepthStencil.Release(); + RebindRenderTargets(); + } + } + + void DeviceContextD3D11Impl::SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil ) + { + if( TDeviceContextBase::SetRenderTargets( NumRenderTargets, ppRenderTargets, pDepthStencil ) ) + { + for( Uint32 RT = 0; RT < NumRenderTargets; ++RT ) + if( ppRenderTargets[RT] ) + { + UnbindTextureFromInput( ppRenderTargets[RT]->GetTexture() ); + } + if( pDepthStencil ) + UnbindTextureFromInput( pDepthStencil->GetTexture() ); + + RebindRenderTargets(); + + // Set the viewport to match the render target size + SetViewports(1, nullptr, 0, 0); + } + } + + template<typename TD3D11ResourceType, typename TSetD3D11ResMethodType> + void SetD3D11ResourcesHelper(ID3D11DeviceContext *pDeviceCtx, + TSetD3D11ResMethodType SetD3D11ResMethod, + UINT StartSlot, UINT NumSlots, + TD3D11ResourceType **ppResources) + { + (pDeviceCtx->*SetD3D11ResMethod)(StartSlot, NumSlots, ppResources); + } + + template<> + void SetD3D11ResourcesHelper(ID3D11DeviceContext *pDeviceCtx, + TSetUnorderedAccessViewsType SetD3D11UAVMethod, + UINT StartSlot, UINT NumSlots, + ID3D11UnorderedAccessView **ppUAVs) + { + (pDeviceCtx->*SetD3D11UAVMethod)(StartSlot, NumSlots, ppUAVs, nullptr); + } + + template<typename TD3D11ResourceType, typename TBoundResourceType, typename TSetD3D11ResMethodType> + void ClearStateCacheInternal(std::vector<TD3D11ResourceType*> &BoundD3D11Res, + std::vector<TBoundResourceType> &BoundRes, + TSetD3D11ResMethodType SetD3D11ResMethod, + ID3D11DeviceContext *pDeviceCtx) + { + if( BoundD3D11Res.size() ) + { + memset( BoundD3D11Res.data(), 0, BoundD3D11Res.size() * sizeof( BoundD3D11Res[0] ) ); + SetD3D11ResourcesHelper( pDeviceCtx, SetD3D11ResMethod, 0, static_cast<UINT>(BoundD3D11Res.size()), BoundD3D11Res.data() ); + BoundD3D11Res.clear(); + BoundRes.clear(); + } + } + + void DeviceContextD3D11Impl::ClearShaderStateCache() + { + for( int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType ) + { + ClearStateCacheInternal( m_BoundD3D11CBs [ShaderType], m_BoundCBs [ShaderType], SetCBMethods[ShaderType], m_pd3d11DeviceContext ); + ClearStateCacheInternal( m_BoundD3D11SRVs [ShaderType], m_BoundSRVs [ShaderType], SetSRVMethods[ShaderType], m_pd3d11DeviceContext ); + ClearStateCacheInternal( m_BoundD3D11Samplers[ShaderType], m_BoundSamplers[ShaderType], SetSamplerMethods[ShaderType], m_pd3d11DeviceContext ); + ClearStateCacheInternal( m_BoundD3D11UAVs [ShaderType], m_BoundUAVs [ShaderType], SetUAVMethods[ShaderType], m_pd3d11DeviceContext ); + } + + dbgVerifyContextSRVs(); + dbgVerifyContextUAVs(); + dbgVerifyContextSamplers(); + dbgVerifyContextCBs(); + + // We do not unbind vertex buffers and index buffer as this can explicitly + // be done by the user + } + +#ifdef VERIFY_CONTEXT_BINDINGS + + DEFINE_D3D11CTX_FUNC_POINTERS(GetCBMethods, GetConstantBuffers) + DEFINE_D3D11CTX_FUNC_POINTERS(GetSRVMethods, GetShaderResources) + DEFINE_D3D11CTX_FUNC_POINTERS(GetSamplerMethods, GetSamplers) + + typedef decltype (&ID3D11DeviceContext::CSGetUnorderedAccessViews) TGetUnorderedAccessViewsType; + static const TGetUnorderedAccessViewsType GetUAVMethods[] = + { + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + &ID3D11DeviceContext::CSGetUnorderedAccessViews + }; + + /// \tparam MaxResources - Maximum number of resources that can be bound to D3D11 context + /// \tparam TD3D11ResourceType - Type of D3D11 resource being checked (ID3D11ShaderResourceView, + /// ID3D11UnorderedAccessView, ID3D11Buffer or ID3D11SamplerState). + /// \tparam TGetD3D11ResourcesType - Type of the device context method used to get the bound + /// resources + /// \param BoundD3D11ResourcesArr - Pointer to the array of currently bound D3D11 + /// resources, for each shader stage + /// \param GetD3D11ResMethods - Pointer to the array of device context methods to get the bound + /// resources, for each shader stage + /// \param ResourceName - Resource name + /// \param ShaderType - Shader type for which to check the resources. If Diligent::SHADER_TYPE_UNKNOWN + /// is provided, all shader stages will be checked + template<UINT MaxResources, + typename TD3D11ResourceType, + typename TGetD3D11ResourcesType> + void DeviceContextD3D11Impl::dbgVerifyContextResources(std::vector<TD3D11ResourceType> BoundD3D11ResourcesArr[], + TGetD3D11ResourcesType GetD3D11ResMethods[], + const Char *ResourceName, + SHADER_TYPE ShaderType) + { + int iStartInd = 0, iEndInd = NumShaderTypes; + if( ShaderType != SHADER_TYPE_UNKNOWN ) + { + iStartInd = GetShaderTypeIndex(ShaderType); + iEndInd = iStartInd + 1; + } + for( int iShaderTypeInd = iStartInd; iShaderTypeInd < iEndInd; ++iShaderTypeInd ) + { + const auto ShaderName = GetShaderTypeLiteralName( GetShaderTypeFromIndex(iShaderTypeInd) ); + TD3D11ResourceType pctxResources[MaxResources] = {}; + auto GetResMethod = GetD3D11ResMethods[iShaderTypeInd]; + if( GetResMethod ) + { + (m_pd3d11DeviceContext->*GetResMethod)(0, _countof( pctxResources ), pctxResources); + } + const auto& BoundResources = BoundD3D11ResourcesArr[iShaderTypeInd]; + auto NumBoundResources = BoundResources.size(); + for( Uint32 Slot = 0; Slot < _countof( pctxResources ); ++Slot ) + { + if( Slot < NumBoundResources ) + { + VERIFY( BoundResources[Slot] == pctxResources[Slot], ResourceName, " binding mismatch found for ", ShaderName, " shader type at slot ", Slot ) + } + else + { + VERIFY( pctxResources[Slot] == nullptr, ResourceName, " binding mismatch found for ", ShaderName, " shader type at slot ", Slot ) + } + + if( pctxResources[Slot] ) + pctxResources[Slot]->Release(); + } + } + } + + void DeviceContextD3D11Impl::dbgVerifyContextSRVs(SHADER_TYPE ShaderType) + { + dbgVerifyContextResources<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>( m_BoundD3D11SRVs, GetSRVMethods, "SRV", ShaderType ); + } + + void DeviceContextD3D11Impl::dbgVerifyContextUAVs(SHADER_TYPE ShaderType) + { + dbgVerifyContextResources<D3D11_PS_CS_UAV_REGISTER_COUNT>( m_BoundD3D11UAVs, GetUAVMethods, "UAV", ShaderType ); + } + + void DeviceContextD3D11Impl::dbgVerifyContextSamplers(SHADER_TYPE ShaderType) + { + dbgVerifyContextResources<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>( m_BoundD3D11Samplers, GetSamplerMethods, "Sampler", ShaderType ); + } + + void DeviceContextD3D11Impl::dbgVerifyContextCBs(SHADER_TYPE ShaderType) + { + dbgVerifyContextResources<D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>( m_BoundD3D11CBs, GetCBMethods, "Constant buffer", ShaderType ); + } + + void DeviceContextD3D11Impl::dbgVerifyIndexBuffer() + { + RefCntAutoPtr<ID3D11Buffer> pctxIndexBuffer; + DXGI_FORMAT Fmt = DXGI_FORMAT_UNKNOWN; + UINT Offset = 0; + m_pd3d11DeviceContext->IAGetIndexBuffer( &pctxIndexBuffer, &Fmt, &Offset ); + if( m_BoundD3D11IndexBuffer && !pctxIndexBuffer ) + UNEXPECTED( "D3D11 index buffer is not bound to the context" ); + if( !m_BoundD3D11IndexBuffer && pctxIndexBuffer ) + UNEXPECTED( "Unexpected D3D11 index buffer is bound to the context" ); + + if( m_BoundD3D11IndexBuffer && pctxIndexBuffer ) + { + VERIFY(m_BoundD3D11IndexBuffer == pctxIndexBuffer, "Index buffer binding mismatch detected"); + VERIFY(m_BoundD3D11IndexFmt == Fmt, "Index buffer format mismatch detected"); + VERIFY(m_BoundD3D11IndexDataStartOffset == Offset, "Index buffer offset mismatch detected"); + } + } + + void DeviceContextD3D11Impl::dbgVerifyVertexBuffers() + { + const Uint32 MaxVBs = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; + ID3D11Buffer *pVBs[MaxVBs]; + UINT Strides[MaxVBs]; + UINT Offsets[MaxVBs]; + m_pd3d11DeviceContext->IAGetVertexBuffers( 0, MaxVBs, pVBs, Strides, Offsets ); + auto NumBoundVBs = m_BoundD3D11VertexBuffers.size(); + VERIFY(m_BoundD3D11VBStrides.size() == NumBoundVBs, "Unexpected bound D3D11 VB stride array size"); + VERIFY(m_BoundD3D11VBOffsets.size() == NumBoundVBs, "Unexpected bound D3D11 VB offset array size"); + for( Uint32 Slot = 0; Slot < MaxVBs; ++Slot ) + { + if( Slot < NumBoundVBs ) + { + const auto &BoundD3D11VB = m_BoundD3D11VertexBuffers[Slot]; + auto BoundVBStride = m_BoundD3D11VBStrides[Slot]; + auto BoundVBOffset = m_BoundD3D11VBOffsets[Slot]; + if(BoundD3D11VB && !pVBs[Slot] ) + VERIFY( pVBs[Slot] == nullptr, "Missing D3D11 buffer detected at slot ", Slot ); + if(!BoundD3D11VB && pVBs[Slot] ) + VERIFY( pVBs[Slot] == nullptr, "Unexpected D3D11 buffer detected at slot ", Slot ); + if( BoundD3D11VB && pVBs[Slot] ) + { + VERIFY( BoundD3D11VB == pVBs[Slot], "Vertex buffer mismatch detected at slot ", Slot ); + VERIFY( BoundVBOffset == Offsets[Slot], "Offset mismatch detected at slot ", Slot ); + VERIFY( BoundVBStride == Strides[Slot], "Stride mismatch detected at slot ", Slot ); + } + } + else + { + VERIFY( pVBs[Slot] == nullptr, "Unexpected D3D11 buffer detected at slot ", Slot ); + } + + if( pVBs[Slot] ) + pVBs[Slot]->Release(); + } + } + + template<typename TD3D11ShaderType, typename TGetShaderMethodType> + void dbgVerifyShadersHelper(SHADER_TYPE ShaderType, + const CComPtr<ID3D11DeviceChild> BoundD3DShaders[], + ID3D11DeviceContext *pCtx, + TGetShaderMethodType GetShaderMethod) + { + RefCntAutoPtr<TD3D11ShaderType> pctxShader; + (pCtx->*GetShaderMethod)(&pctxShader, nullptr, nullptr); + const auto &BoundShader = BoundD3DShaders[GetShaderTypeIndex( ShaderType )]; + VERIFY( BoundShader == pctxShader, GetShaderTypeLiteralName(ShaderType), " binding mismatch detected" ); + } + void DeviceContextD3D11Impl::dbgVerifyShaders() + { +#define VERIFY_SHADER(NAME, Name, N) dbgVerifyShadersHelper<ID3D11##Name##Shader>(SHADER_TYPE_##NAME, m_BoundD3DShaders, m_pd3d11DeviceContext, &ID3D11DeviceContext::N##SGetShader ) + // These shaders which are not set will be unbound from the D3D11 device context + VERIFY_SHADER( VERTEX, Vertex, V ); + VERIFY_SHADER( PIXEL, Pixel, P ); + VERIFY_SHADER( GEOMETRY, Geometry, G ); + VERIFY_SHADER( DOMAIN, Domain, D ); + VERIFY_SHADER( HULL, Hull, H ); + VERIFY_SHADER( COMPUTE, Compute, C ); + } + +#endif + +} diff --git a/Graphics/GraphicsEngineD3D11/src/GraphicsEngineD3D11.def b/Graphics/GraphicsEngineD3D11/src/GraphicsEngineD3D11.def new file mode 100644 index 00000000..9414b724 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/GraphicsEngineD3D11.def @@ -0,0 +1,3 @@ +EXPORTS + CreateDeviceAndImmediateContextD3D11 + CreateSwapChainD3D11
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/src/RasterizerStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RasterizerStateD3D11Impl.cpp new file mode 100644 index 00000000..90bd9092 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/RasterizerStateD3D11Impl.cpp @@ -0,0 +1,110 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "RasterizerStateD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" + +namespace Diligent +{ + +D3D11_FILL_MODE FillMode2D3D11FillMode(FILL_MODE FillMode) +{ + static bool bIsInit = false; + static D3D11_FILL_MODE D3D11FillModes[FILL_MODE_NUM_MODES] = {}; + if( !bIsInit ) + { + D3D11FillModes[ FILL_MODE_WIREFRAME ] = D3D11_FILL_WIREFRAME; + D3D11FillModes[ FILL_MODE_SOLID ] = D3D11_FILL_SOLID; + + bIsInit = true; + } + if( FILL_MODE_UNDEFINED < FillMode && FillMode < FILL_MODE_NUM_MODES ) + { + auto D3D11FillMode = D3D11FillModes[FillMode]; + VERIFY( D3D11FillMode != 0, "Incorrect fill mode" ); + return D3D11FillModes[FillMode]; + } + else + { + UNEXPECTED( "Incorrect fill mode (", FillMode, ")" ) + return static_cast<D3D11_FILL_MODE>(0); + } +} + +D3D11_CULL_MODE CullMode2D3D11CullMode( CULL_MODE CullMode ) +{ + static bool bIsInit = false; + static D3D11_CULL_MODE D3D11CullModes[CULL_MODE_NUM_MODES] = {}; + if( !bIsInit ) + { + D3D11CullModes[ CULL_MODE_NONE ] = D3D11_CULL_NONE; + D3D11CullModes[ CULL_MODE_FRONT ] = D3D11_CULL_FRONT; + D3D11CullModes[ CULL_MODE_BACK ] = D3D11_CULL_BACK; + + bIsInit = true; + } + + if( CULL_MODE_UNDEFINED < CullMode && CullMode < CULL_MODE_NUM_MODES ) + { + auto D3D11CullMode = D3D11CullModes[CullMode]; + VERIFY( D3D11CullMode != 0, "Incorrect cull mode" ); + return D3D11CullMode; + } + else + { + UNEXPECTED( "Incorrect cull mode (", CullMode, ")" ) + return static_cast<D3D11_CULL_MODE>(0); + } +} + +RasterizerStateD3D11Impl::RasterizerStateD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, + const RasterizerStateDesc& RasterizerStateDesc) : + TRasterizerStateBase(pRenderDeviceD3D11, RasterizerStateDesc) +{ + D3D11_RASTERIZER_DESC D3D11RSDesc; + + D3D11RSDesc.FillMode = FillMode2D3D11FillMode(RasterizerStateDesc.FillMode); + D3D11RSDesc.CullMode = CullMode2D3D11CullMode(RasterizerStateDesc.CullMode); + D3D11RSDesc.FrontCounterClockwise = RasterizerStateDesc.FrontCounterClockwise ? TRUE : FALSE; + D3D11RSDesc.DepthBias = RasterizerStateDesc.DepthBias; + D3D11RSDesc.DepthBiasClamp = RasterizerStateDesc.DepthBiasClamp; + D3D11RSDesc.SlopeScaledDepthBias = RasterizerStateDesc.SlopeScaledDepthBias; + D3D11RSDesc.DepthClipEnable = RasterizerStateDesc.DepthClipEnable ? TRUE : FALSE; + D3D11RSDesc.ScissorEnable = RasterizerStateDesc.ScissorEnable ? TRUE : FALSE; + D3D11RSDesc.AntialiasedLineEnable = RasterizerStateDesc.AntialiasedLineEnable ? TRUE : FALSE; + D3D11RSDesc.MultisampleEnable = D3D11RSDesc.AntialiasedLineEnable; + + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRasterizerState( &D3D11RSDesc, &m_pd3d11RasterizerState ), + "Failed to create D3D11 rasterizer state" ); +} + +RasterizerStateD3D11Impl::~RasterizerStateD3D11Impl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( RasterizerStateD3D11Impl, IID_RasterizerStateD3D11, TRasterizerStateBase ) + +} diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp new file mode 100644 index 00000000..c828493e --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp @@ -0,0 +1,440 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "RenderDeviceD3D11Impl.h" +#include "DeviceContextD3D11Impl.h" +#include "BufferD3D11Impl.h" +#include "VertexDescD3D11Impl.h" +#include "ShaderD3D11Impl.h" +#include "Texture1D_D3D11.h" +#include "Texture2D_D3D11.h" +#include "Texture3D_D3D11.h" +#include "SamplerD3D11Impl.h" +#include "D3D11TypeConversions.h" +#include "TextureViewD3D11Impl.h" +#include "DSStateD3D11Impl.h" +#include "RasterizerStateD3D11Impl.h" +#include "BlendStateD3D11Impl.h" + +namespace Diligent +{ + +RenderDeviceD3D11Impl :: RenderDeviceD3D11Impl(ID3D11Device *pd3d11Device) : + m_pd3d11Device(pd3d11Device) +{ + m_DeviceCaps.DevType = DeviceType::DirectX; + m_DeviceCaps.MajorVersion = 11; + m_DeviceCaps.MinorVersion = 0; + m_DeviceCaps.bSeparableProgramSupported = true; + + FlagSupportedTexFormats(); +} + +void RenderDeviceD3D11Impl::FlagSupportedTexFormats() +{ +#define FLAG_FORMAT(Fmt, IsSupported)\ + m_TextureFormatsInfo[Fmt].Supported = IsSupported; + + FLAG_FORMAT(TEX_FORMAT_RGBA32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R32G8X24_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D32_FLOAT_S8X24_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_X32_TYPELESS_G8X24_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R11G11B10_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_R32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_R32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R24G8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D24_UNORM_S8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R24_UNORM_X8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_X24_TYPELESS_G8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_R16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_D16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_R8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_R8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_A8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGB9E5_SHAREDEXP, true); + FLAG_FORMAT(TEX_FORMAT_RG8_B8G8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_G8R8_G8B8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC1_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC1_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC2_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC2_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC3_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC3_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC3_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC4_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC4_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC4_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC5_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC5_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC5_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_B5G6R5_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_B5G5R5A1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_UF16, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_SF16, true); + FLAG_FORMAT(TEX_FORMAT_BC7_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC7_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC7_UNORM_SRGB, true); +} + +bool CreateTestTexture1D(ID3D11Device *pDevice, const D3D11_TEXTURE1D_DESC &TexDesc) +{ + // Set the texture pointer address to nullptr to validate input parameters + // without creating the texture + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476520(v=vs.85).aspx + HRESULT hr = pDevice->CreateTexture1D( &TexDesc, nullptr, nullptr ); + return hr == S_FALSE; // S_FALSE means that input parameters passed validation +} + +bool CreateTestTexture2D(ID3D11Device *pDevice, const D3D11_TEXTURE2D_DESC &TexDesc) +{ + // Set the texture pointer address to nullptr to validate input parameters + // without creating the texture + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476521(v=vs.85).aspx + HRESULT hr = pDevice->CreateTexture2D( &TexDesc, nullptr, nullptr ); + return hr == S_FALSE; // S_FALSE means that input parameters passed validation +} + +bool CreateTestTexture3D(ID3D11Device *pDevice, const D3D11_TEXTURE3D_DESC &TexDesc) +{ + // Set the texture pointer address to nullptr to validate input parameters + // without creating the texture + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476522(v=vs.85).aspx + HRESULT hr = pDevice->CreateTexture3D( &TexDesc, nullptr, nullptr ); + return hr == S_FALSE; // S_FALSE means that input parameters passed validation +} + +void RenderDeviceD3D11Impl::TestTextureFormat( TEXTURE_FORMAT TexFormat ) +{ + auto &TexFormatInfo = m_TextureFormatsInfo[TexFormat]; + VERIFY( TexFormatInfo.Supported, "Texture format is not supported" ); + + auto DXGIFormat = TexFormatToDXGI_Format(TexFormat); + UINT DefaultBind = 0; + if( TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL ) + DefaultBind = D3D11_BIND_DEPTH_STENCIL; + else + DefaultBind = D3D11_BIND_SHADER_RESOURCE; + + const int TestTextureDim = 32; + const int TestTextureDepth = 8; + + // Create test texture 1D + TexFormatInfo.Tex1DFmt = false; + if( TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED ) + { + D3D11_TEXTURE1D_DESC Tex1DDesc = + { + TestTextureDim, // UINT Width; + 1, // UINT MipLevels; + 1, // UINT ArraySize; + DXGIFormat, // DXGI_FORMAT Format; + D3D11_USAGE_DEFAULT, // D3D11_USAGE Usage; + DefaultBind, // UINT BindFlags; + 0, // UINT CPUAccessFlags; + 0 // UINT MiscFlags; + }; + TexFormatInfo.Tex1DFmt = CreateTestTexture1D(m_pd3d11Device, Tex1DDesc ); + } + + // Create test texture 2D + TexFormatInfo.Tex2DFmt = false; + TexFormatInfo.TexCubeFmt = false; + TexFormatInfo.ColorRenderable = false; + TexFormatInfo.DepthRenderable = false; + TexFormatInfo.SupportsMS = false; + { + D3D11_TEXTURE2D_DESC Tex2DDesc = + { + TestTextureDim, // UINT Width; + TestTextureDim, // UINT Height; + 1, // UINT MipLevels; + 1, // UINT ArraySize; + DXGIFormat, // DXGI_FORMAT Format; + { 1, 0 }, // DXGI_SAMPLE_DESC SampleDesc; + D3D11_USAGE_DEFAULT, // D3D11_USAGE Usage; + DefaultBind, // UINT BindFlags; + 0, // UINT CPUAccessFlags; + 0, // UINT MiscFlags; + }; + TexFormatInfo.Tex2DFmt = CreateTestTexture2D( m_pd3d11Device, Tex2DDesc ); + + if( TexFormatInfo.Tex2DFmt ) + { + { + D3D11_TEXTURE2D_DESC CubeTexDesc = Tex2DDesc; + CubeTexDesc.ArraySize = 6; + CubeTexDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + TexFormatInfo.TexCubeFmt = CreateTestTexture2D( m_pd3d11Device, CubeTexDesc ); + } + + if( TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL ) + { + Tex2DDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + TexFormatInfo.DepthRenderable = CreateTestTexture2D( m_pd3d11Device, Tex2DDesc ); + + if( TexFormatInfo.DepthRenderable ) + { + Tex2DDesc.SampleDesc.Count = 4; + TexFormatInfo.SupportsMS = CreateTestTexture2D( m_pd3d11Device, Tex2DDesc ); + } + } + else if( TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED ) + { + Tex2DDesc.BindFlags = D3D11_BIND_RENDER_TARGET; + TexFormatInfo.ColorRenderable = CreateTestTexture2D( m_pd3d11Device, Tex2DDesc ); + if( TexFormatInfo.ColorRenderable ) + { + Tex2DDesc.SampleDesc.Count = 4; + TexFormatInfo.SupportsMS = CreateTestTexture2D( m_pd3d11Device, Tex2DDesc ); + } + } + } + } + + // Create test texture 3D + TexFormatInfo.Tex3DFmt = false; + // 3D textures do not support depth formats + if( !(TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL) ) + { + D3D11_TEXTURE3D_DESC Tex3DDesc = + { + TestTextureDim, // UINT Width; + TestTextureDim, // UINT Height; + TestTextureDepth, // UINT Depth; + 1, // UINT MipLevels; + DXGIFormat, // DXGI_FORMAT Format; + D3D11_USAGE_DEFAULT,// D3D11_USAGE Usage; + DefaultBind, // UINT BindFlags; + 0, // UINT CPUAccessFlags; + 0 // UINT MiscFlags; + }; + TexFormatInfo.Tex3DFmt = CreateTestTexture3D( m_pd3d11Device, Tex3DDesc ); + } +} + +IMPLEMENT_QUERY_INTERFACE( RenderDeviceD3D11Impl, IID_RenderDeviceD3D11, TRenderDeviceBase ) + +void RenderDeviceD3D11Impl :: CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer) +{ + CreateDeviceObject("buffer", BuffDesc, ppBuffer, + [&]() + { + BufferD3D11Impl *pBufferD3D11( new BufferD3D11Impl( this, BuffDesc, BuffData ) ); + pBufferD3D11->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); + pBufferD3D11->CreateDefaultViews(); + OnCreateDeviceObject( pBufferD3D11 ); + } + ); +} + +void RenderDeviceD3D11Impl :: CreateVertexDescription(const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc) +{ + CreateDeviceObject( "vertex description", LayoutDesc, ppVertexDesc, + [&]() + { + VertexDescD3D11Impl *pDescD3D11( new VertexDescD3D11Impl( this, LayoutDesc, pVertexShader ) ); + pDescD3D11->QueryInterface( IID_VertexDescription, reinterpret_cast<IObject**>(ppVertexDesc) ); + + OnCreateDeviceObject( pDescD3D11 ); + } + ); +} + +void RenderDeviceD3D11Impl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader) +{ + CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, + [&]() + { + ShaderD3D11Impl *pShaderD3D11( new ShaderD3D11Impl( this, ShaderCreationAttribs ) ); + pShaderD3D11->QueryInterface( IID_Shader, reinterpret_cast<IObject**>(ppShader) ); + + OnCreateDeviceObject( pShaderD3D11 ); + } + ); +} + +void RenderDeviceD3D11Impl :: CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture) +{ + CreateDeviceObject( "texture", TexDesc, ppTexture, + [&]() + { + TextureBaseD3D11 *pTextureD3D11 = nullptr; + switch( TexDesc.Type ) + { + case TEXTURE_TYPE_1D: + case TEXTURE_TYPE_1D_ARRAY: + pTextureD3D11 = new Texture1D_D3D11( this, TexDesc, Data ); + break; + + case TEXTURE_TYPE_2D: + case TEXTURE_TYPE_2D_ARRAY: + pTextureD3D11 = new Texture2D_D3D11( this, TexDesc, Data ); + break; + + case TEXTURE_TYPE_3D: + pTextureD3D11 = new Texture3D_D3D11( this, TexDesc, Data ); + break; + + default: LOG_ERROR_AND_THROW( "Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)" ); + } + pTextureD3D11->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); + pTextureD3D11->CreateDefaultViews(); + OnCreateDeviceObject( pTextureD3D11 ); + } + ); +} + +void RenderDeviceD3D11Impl :: CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler) +{ + CreateDeviceObject( "sampler", SamplerDesc, ppSampler, + [&]() + { + m_SamplersRegistry.Find( SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler) ); + if( *ppSampler == nullptr ) + { + SamplerD3D11Impl *pSamplerD3D11( new SamplerD3D11Impl( this, SamplerDesc ) ); + pSamplerD3D11->QueryInterface( IID_Sampler, reinterpret_cast<IObject**>(ppSampler) ); + OnCreateDeviceObject( pSamplerD3D11 ); + m_SamplersRegistry.Add( SamplerDesc, *ppSampler ); + } + } + ); +} + +void RenderDeviceD3D11Impl::CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState ) +{ + CreateDeviceObject( "depth-stencil state", DSSDesc, ppDepthStencilState, + [&]() + { + m_DSSRegistry.Find( DSSDesc, reinterpret_cast<IDeviceObject**>(ppDepthStencilState) ); + if( *ppDepthStencilState == nullptr ) + { + DSStateD3D11Impl *pDepthStencilStateD3D11( new DSStateD3D11Impl( this, DSSDesc ) ); + pDepthStencilStateD3D11->QueryInterface( IID_DepthStencilState, reinterpret_cast<IObject**>(ppDepthStencilState) ); + OnCreateDeviceObject( pDepthStencilStateD3D11 ); + m_DSSRegistry.Add( DSSDesc, *ppDepthStencilState ); + } + } + ); +} + +void RenderDeviceD3D11Impl::CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState ) +{ + CreateDeviceObject( "rasterizer state", RSDesc, ppRasterizerState, + [&]() + { + m_RSRegistry.Find( RSDesc, reinterpret_cast<IDeviceObject**>(ppRasterizerState) ); + if( *ppRasterizerState == nullptr ) + { + RasterizerStateD3D11Impl *pRasterizerStateD3D11( new RasterizerStateD3D11Impl( this, RSDesc ) ); + pRasterizerStateD3D11->QueryInterface( IID_RasterizerState, reinterpret_cast<IObject**>(ppRasterizerState) ); + OnCreateDeviceObject( pRasterizerStateD3D11 ); + m_RSRegistry.Add( RSDesc, *ppRasterizerState ); + } + } + ); +} + + +void RenderDeviceD3D11Impl::CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState ) +{ + CreateDeviceObject( "blend state", BSDesc, ppBlendState, + [&]() + { + m_BSRegistry.Find( BSDesc, reinterpret_cast<IDeviceObject**>(ppBlendState) ); + if( *ppBlendState == nullptr ) + { + BlendStateD3D11Impl *pBlendStateD3D11( new BlendStateD3D11Impl( this, BSDesc ) ); + pBlendStateD3D11->QueryInterface( IID_BlendState, reinterpret_cast<IObject**>(ppBlendState) ); + OnCreateDeviceObject( pBlendStateD3D11 ); + m_BSRegistry.Add( BSDesc, *ppBlendState ); + } + } + ); +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp new file mode 100644 index 00000000..ee040562 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp @@ -0,0 +1,198 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "RenderDeviceFactoryD3D11.h" +#include "RenderDeviceD3D11Impl.h" +#include "DeviceContextD3D11Impl.h" +#include "SwapChainD3D11Impl.h" +#include "D3D11TypeConversions.h" +#include <Windows.h> + +using namespace Diligent; +using namespace Diligent; + +extern "C" +{ + +#if defined(_DEBUG) +// Check for SDK Layer support. +inline bool SdkLayersAvailable() +{ + HRESULT hr = D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device. + 0, + D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers. + nullptr, // Any feature level will do. + 0, + D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. + nullptr, // No need to keep the D3D device reference. + nullptr, // No need to know the feature level. + nullptr // No need to keep the D3D device context reference. + ); + + return SUCCEEDED(hr); +} +#endif + +void CreateDeviceAndImmediateContextD3D11( const EngineCreationAttribs& CreationAttribs, IRenderDevice **ppDevice, Diligent::IDeviceContext **ppContext ) +{ + VERIFY( ppDevice && ppContext, "Null pointer is provided" ); + if( !ppDevice || !ppContext ) + return; + + *ppDevice = nullptr; + *ppContext = nullptr; + + try + { + // This flag adds support for surfaces with a different color channel ordering + // than the API default. It is required for compatibility with Direct2D. + // D3D11_CREATE_DEVICE_BGRA_SUPPORT; + UINT creationFlags = 0; + + #if defined(_DEBUG) + if (SdkLayersAvailable()) + { + // If the project is in a debug build, enable debugging via SDK Layers with this flag. + creationFlags |= D3D11_CREATE_DEVICE_DEBUG; + } + #endif + + // This array defines the set of DirectX hardware feature levels this app will support. + // Note the ordering should be preserved. + // Don't forget to declare your application's minimum required feature level in its + // description. All applications are assumed to support 9.1 unless otherwise stated. + D3D_FEATURE_LEVEL featureLevels[] = + { +#ifdef PLATFORM_WINDOWS_STORE + D3D_FEATURE_LEVEL_11_1, +#endif + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1 + }; + + // Create the Direct3D 11 API device object and a corresponding context. + RefCntAutoPtr<ID3D11Device> pd3d11Device; + RefCntAutoPtr<ID3D11DeviceContext> pd3d11Context; + + D3D_FEATURE_LEVEL d3dFeatureLevel = D3D_FEATURE_LEVEL_11_0; + HRESULT hr = D3D11CreateDevice( + nullptr, // Specify nullptr to use the default adapter. + D3D_DRIVER_TYPE_HARDWARE, // Create a device using the hardware graphics driver. + 0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE. + creationFlags, // Set debug and Direct2D compatibility flags. + featureLevels, // List of feature levels this app can support. + ARRAYSIZE(featureLevels), // Size of the list above. + D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. + &pd3d11Device, // Returns the Direct3D device created. + &d3dFeatureLevel, // Returns feature level of device created. + &pd3d11Context // Returns the device immediate context. + ); + + if (FAILED(hr)) + { + // If the initialization fails, fall back to the WARP device. + // For more information on WARP, see: + // http://go.microsoft.com/fwlink/?LinkId=286690 + hr = D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device. + 0, + creationFlags, + featureLevels, + ARRAYSIZE(featureLevels), + D3D11_SDK_VERSION, + &pd3d11Device, + &d3dFeatureLevel, + &pd3d11Context + ); + CHECK_D3D_RESULT_THROW( hr, "Failed to create D3D11 Device and swap chain" ); + } + + RenderDeviceD3D11Impl *pRenderDeviceD3D11( new RenderDeviceD3D11Impl( pd3d11Device ) ); + pRenderDeviceD3D11->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); + + RefCntAutoPtr<DeviceContextD3D11Impl> pDeviceContextD3D11( new DeviceContextD3D11Impl( pRenderDeviceD3D11, pd3d11Context) ); + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceD3D11 will + // keep a weak reference to the context + pDeviceContextD3D11->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppContext) ); + pRenderDeviceD3D11->SetImmediateContext(pDeviceContextD3D11); + pDeviceContextD3D11->CreateDefaultStates(); + } + catch( const std::runtime_error & ) + { + if( *ppDevice ) + { + (*ppDevice)->Release(); + *ppDevice = nullptr; + } + if( *ppContext ) + { + (*ppContext)->Release(); + *ppContext = nullptr; + } + + LOG_ERROR( "Failed to create device and immediate context" ); + } +} + +void CreateSwapChainD3D11( IRenderDevice *pDevice, Diligent::IDeviceContext *pImmediateContext, const SwapChainDesc& SwapChainDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain ) +{ + VERIFY( ppSwapChain, "Null pointer is provided" ); + if( !ppSwapChain ) + return; + + *ppSwapChain = nullptr; + + try + { + auto *pDeviceD3D11 = ValidatedCast<RenderDeviceD3D11Impl>( pDevice ); + auto *pDeviceContextD3D11 = ValidatedCast<DeviceContextD3D11Impl>(pImmediateContext); + auto *pSwapChainD3D11 = new SwapChainD3D11Impl(SwapChainDesc, pDeviceD3D11, pDeviceContextD3D11, pNativeWndHandle); + pSwapChainD3D11->QueryInterface( IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); + + pDeviceContextD3D11->SetSwapChain(pSwapChainD3D11); + // Bind default render target + pDeviceContextD3D11->SetRenderTargets( 0, nullptr, nullptr ); + // Set default viewport + pDeviceContextD3D11->SetViewports( 1, nullptr, 0, 0 ); + } + catch( const std::runtime_error & ) + { + if( *ppSwapChain ) + { + (*ppSwapChain)->Release(); + *ppSwapChain = nullptr; + } + + LOG_ERROR( "Failed to create the swap chain" ); + } +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/SamplerD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SamplerD3D11Impl.cpp new file mode 100644 index 00000000..3aa13c74 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/SamplerD3D11Impl.cpp @@ -0,0 +1,60 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "SamplerD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" +#include "D3D11TypeConversions.h" + +namespace Diligent +{ + +SamplerD3D11Impl::SamplerD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const SamplerDesc& SamplerDesc) : + TSamplerBase(pRenderDeviceD3D11, SamplerDesc) +{ + auto *pd3d11Device = pRenderDeviceD3D11->GetD3D11Device(); + D3D11_SAMPLER_DESC D3D11SamplerDesc = + { + FilterTypeToD3D11Filter(SamplerDesc.MinFilter, SamplerDesc.MagFilter, SamplerDesc.MipFilter), + TexAddressModeToD3D11AddressMode(SamplerDesc.AddressU), + TexAddressModeToD3D11AddressMode(SamplerDesc.AddressV), + TexAddressModeToD3D11AddressMode(SamplerDesc.AddressW), + SamplerDesc.MipLODBias, + SamplerDesc.MaxAnisotropy, + ComparisonFuncToD3D11ComparisonFunc(SamplerDesc.ComparisonFunc), + {SamplerDesc.BorderColor[0], SamplerDesc.BorderColor[1], SamplerDesc.BorderColor[2], SamplerDesc.BorderColor[3]}, + SamplerDesc.MinLOD, + SamplerDesc.MaxLOD + }; + CHECK_D3D_RESULT_THROW( pd3d11Device->CreateSamplerState(&D3D11SamplerDesc, &m_pd3dSampler), + "Failed to create the Direct3D11 sampler"); +} + +SamplerD3D11Impl::~SamplerD3D11Impl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( SamplerD3D11Impl, IID_SamplerD3D11, TSamplerBase ) + +} diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp new file mode 100644 index 00000000..651261ac --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp @@ -0,0 +1,838 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include <D3Dcompiler.h> + +#include "ShaderD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" +#include "StringTools.h" +#include "ResourceMapping.h" +#include "BufferD3D11Impl.h" +#include "GraphicsUtilities.h" +#include "TextureViewD3D11Impl.h" +#include "SamplerD3D11Impl.h" +#include "BufferViewD3D11Impl.h" +#include "D3D11DebugUtilities.h" +#include "DataBlobImpl.h" + +using namespace Diligent; + +namespace Diligent +{ +const String ShaderD3D11Impl::m_SamplerSuffix = "_sampler"; +const UINT InvalidBindPoint = std::numeric_limits<UINT>::max(); + +static const Char* g_HLSLDefinitions = +{ + #include "HLSLDefinitions_inc.fxh" +}; + + +class D3DIncludeImpl : public ID3DInclude +{ +public: + D3DIncludeImpl(IShaderSourceInputStreamFactory *pStreamFactory) : + m_pStreamFactory(pStreamFactory) + { + + } + + STDMETHOD( Open )(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) + { + RefCntAutoPtr<IFileStream> pSourceStream; + m_pStreamFactory->CreateInputStream( pFileName, &pSourceStream ); + if( pSourceStream == nullptr ) + { + LOG_ERROR( "Failed to open shader include file ", pFileName, ". Check that the file exists" ); + return E_FAIL; + } + + RefCntAutoPtr<Diligent::IDataBlob> pFileData( new Diligent::DataBlobImpl ); + pSourceStream->Read( pFileData ); + *ppData = pFileData->GetDataPtr(); + *pBytes = static_cast<UINT>( pFileData->GetSize() ); + + m_DataBlobs.insert( std::make_pair(*ppData, pFileData) ); + + return S_OK; + } + + STDMETHOD( Close )(THIS_ LPCVOID pData) + { + m_DataBlobs.erase( pData ); + return S_OK; + } + +private: + IShaderSourceInputStreamFactory *m_pStreamFactory; + std::unordered_map< LPCVOID, RefCntAutoPtr<Diligent::IDataBlob> > m_DataBlobs; +}; + +static +HRESULT CompileShader( const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + IShaderSourceInputStreamFactory *pIncludeStreamFactory, + LPCSTR profile, + ID3DBlob **ppBlobOut ) +{ + DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; +#if defined( DEBUG ) || defined( _DEBUG ) + // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders. + // Setting this flag improves the shader debugging experience, but still allows + // the shaders to be optimized and to run exactly the way they will run in + // the release configuration of this program. + dwShaderFlags |= D3DCOMPILE_DEBUG; +#else + // Warning: do not use this flag as it causes shader compiler to fail the compilation and + // report strange errors: + // dwShaderFlags |= D3D10_SHADER_OPTIMIZATION_LEVEL3; +#endif + HRESULT hr; + do + { + CComPtr<ID3DBlob> errors; + auto SourceLen = strlen(Source); + + D3DIncludeImpl IncludeImpl(pIncludeStreamFactory); + hr = D3DCompile( Source, SourceLen, NULL, pDefines, &IncludeImpl, strFunctionName, profile, dwShaderFlags, 0, ppBlobOut, &errors ); + + if( FAILED(hr) || errors ) + { + std::wstringstream errorss; + ComErrorDesc ErrDesc(hr); + if( FAILED(hr) ) + Diligent::FormatMsg( errorss, "Failed to compile shader\n" ); + else + Diligent::FormatMsg( errorss, "Shader compiler output:\n" ); + Diligent::FormatMsg( errorss, ErrDesc.Get(), "\n" ); + if( errors ) + Diligent::FormatMsg( errorss, (char*)errors->GetBufferPointer() ); + auto ErrorDesc = errorss.str(); + OutputDebugString( ErrorDesc.c_str() ); + if( FAILED(hr) +#ifdef PLATFORM_WINDOWS + && IDRETRY != MessageBox( NULL, ErrorDesc.c_str() , L"FX Error", MB_ICONERROR | (Source == nullptr ? MB_ABORTRETRYIGNORE : 0) ) +#endif + ) + { + break; + } + } + } while( FAILED(hr) ); + return hr; +} + +const char* DXShaderProfileToString(SHADER_PROFILE DXProfile) +{ + return "5_0"; + //switch(DXProfile) + //{ + // case DX_SHADER_PROFILE_4_0: return "4_0"; + // case DX_SHADER_PROFILE_5_0: return "5_0"; + // default: UNEXPECTED("Unknown DirectX shader profile" ); return ""; + //} +} + +void ShaderD3D11Impl::LoadShaderResources() +{ + CComPtr<ID3D11ShaderReflection> pShaderReflection; + CHECK_D3D_RESULT_THROW( D3DReflect( m_pShaderByteCode->GetBufferPointer(), m_pShaderByteCode->GetBufferSize(), __uuidof(pShaderReflection), reinterpret_cast<void**>(static_cast<ID3D11ShaderReflection**>(&pShaderReflection)) ), + "Failed to get the shader reflection" ); + + struct ResourceBindInfo + { + String Name; + UINT BindPoint; + }; + + std::vector<ResourceBindInfo> Textures; + std::unordered_map<String, ResourceBindInfo> Samplers; + + D3D11_SHADER_DESC shaderDesc; + memset( &shaderDesc, 0, sizeof(shaderDesc) ); + pShaderReflection->GetDesc( &shaderDesc ); + for( UINT Res = 0; Res < shaderDesc.BoundResources; ++Res ) + { + D3D11_SHADER_INPUT_BIND_DESC BindingDesc; + memset( &BindingDesc, 0, sizeof( BindingDesc ) ); + pShaderReflection->GetResourceBindingDesc( Res, &BindingDesc ); + + switch( BindingDesc.Type ) + { + case D3D_SIT_CBUFFER: + { + ConstBuffBindInfo NewCBInfo(this, BindingDesc.Name, BindingDesc.BindPoint); +#ifdef _DEBUG + std::for_each( m_ConstanBuffers.begin(), m_ConstanBuffers.end(), + [&]( const ConstBuffBindInfo &CBInfo ) + { + VERIFY( CBInfo.Name != BindingDesc.Name, "Constant buffer with the same name already exists" ); + } + ); +#endif + m_ConstanBuffers.emplace_back( NewCBInfo ); + break; + } + + case D3D_SIT_TBUFFER: + { + UNSUPPORTED( "TBuffers are not supported" ); + break; + } + + case D3D_SIT_TEXTURE: + { + + if( BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ) + { + m_BuffSRVs.emplace_back( BuffSRVBindInfo(this, BindingDesc.Name, BindingDesc.BindPoint) ); + } + else + { + ResourceBindInfo NewTextureInfo = { BindingDesc.Name, BindingDesc.BindPoint }; + Textures.emplace_back( NewTextureInfo ); + } + break; + } + + case D3D_SIT_SAMPLER: + { + ResourceBindInfo NewSamplerInfo = { BindingDesc.Name, BindingDesc.BindPoint }; + Samplers.emplace( std::make_pair( BindingDesc.Name, NewSamplerInfo ) ); + break; + } + + case D3D_SIT_UAV_RWTYPED: + { + if( BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ) + { + m_BuffUAVs.push_back( BuffUAVBindInfo( this, BindingDesc.Name, BindingDesc.BindPoint, BindingDesc.Type ) ); + } + else + { + m_TexUAVs.push_back( TexUAVBindInfo( this, BindingDesc.Name, BindingDesc.BindPoint, BindingDesc.Type ) ); + } + break; + } + + case D3D_SIT_STRUCTURED: + { + UNSUPPORTED( "Structured buffers are not supported" ); + break; + } + + case D3D_SIT_UAV_RWSTRUCTURED: + { + m_BuffUAVs.push_back( BuffUAVBindInfo( this, BindingDesc.Name, BindingDesc.BindPoint, BindingDesc.Type ) ); + break; + } + + case D3D_SIT_BYTEADDRESS: + { + UNSUPPORTED( "Byte address buffers are not supported" ); + break; + } + + case D3D_SIT_UAV_RWBYTEADDRESS: + { + m_BuffUAVs.push_back( BuffUAVBindInfo(this, BindingDesc.Name, BindingDesc.BindPoint, BindingDesc.Type) ); + break; + } + + case D3D_SIT_UAV_APPEND_STRUCTURED: + { + UNSUPPORTED( "Append structured buffers are not supported" ); + break; + } + + case D3D_SIT_UAV_CONSUME_STRUCTURED: + { + UNSUPPORTED( "Consume structured buffers are not supported" ); + break; + } + + case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: + { + UNSUPPORTED( "RW structured buffers with counter are not supported" ); + break; + } + } + } + + // Merge texture and sampler list + for( auto it = Textures.begin(); it != Textures.end(); ++it ) + { + auto SamplerName = it->Name + m_SamplerSuffix; + auto SamplerIt = Samplers.find(SamplerName); + UINT SamplerBindPoint = InvalidBindPoint; + if( SamplerIt != Samplers.end() ) + { + VERIFY( SamplerIt->second.Name == SamplerName, "Unexpected sampler name" ); + SamplerBindPoint = SamplerIt->second.BindPoint; + } + else + { + SamplerName = ""; + } + TexAndSamplerBindInfo TexAndSamplerInfo(this, it->Name, it->BindPoint, SamplerName, SamplerBindPoint); + m_TexAndSamplers.emplace_back( TexAndSamplerInfo ); + } + + // After all resources are loaded, we can populate shader variable hash map. + // The map contains raw pointers, but none of the arrays will ever change. +#define STORE_SHADER_VARIABLES(ResArr)\ + { \ + for( auto it = ResArr.begin(); it != ResArr.end(); ++it ) \ + /* HashMapStringKey will make a copy of the string*/ \ + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(it->GetName()), &*it ) ); \ + } + + STORE_SHADER_VARIABLES(m_ConstanBuffers) + STORE_SHADER_VARIABLES(m_TexAndSamplers) + STORE_SHADER_VARIABLES(m_TexUAVs) + STORE_SHADER_VARIABLES(m_BuffUAVs) + STORE_SHADER_VARIABLES(m_BuffSRVs) + +#undef STORE_SHADER_VARIABLES +} + +ShaderD3D11Impl::ShaderD3D11Impl(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const ShaderCreationAttribs &ShaderCreationAttribs) : + TShaderBase(pRenderDeviceD3D11, ShaderCreationAttribs.Desc) +{ + std::string strShaderProfile; + switch(ShaderCreationAttribs.Desc.ShaderType) + { + case SHADER_TYPE_VERTEX: strShaderProfile="vs"; break; + case SHADER_TYPE_PIXEL: strShaderProfile="ps"; break; + case SHADER_TYPE_GEOMETRY:strShaderProfile="gs"; break; + case SHADER_TYPE_HULL: strShaderProfile="hs"; break; + case SHADER_TYPE_DOMAIN: strShaderProfile="ds"; break; + case SHADER_TYPE_COMPUTE: strShaderProfile="cs"; break; + + default: UNEXPECTED( "Unknown shader type" ); + } + strShaderProfile += "_"; + auto *pProfileSuffix = DXShaderProfileToString(ShaderCreationAttribs.Desc.TargetProfile); + strShaderProfile += pProfileSuffix; + + String ShaderSource(g_HLSLDefinitions); + if( ShaderCreationAttribs.Source ) + ShaderSource.append( ShaderCreationAttribs.Source ); + else + { + VERIFY(ShaderCreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null"); + RefCntAutoPtr<IFileStream> pSourceStream; + ShaderCreationAttribs.pShaderSourceStreamFactory->CreateInputStream( ShaderCreationAttribs.FilePath, &pSourceStream ); + RefCntAutoPtr<Diligent::IDataBlob> pFileData( new Diligent::DataBlobImpl ); + pSourceStream->Read( pFileData ); + // Null terminator is not read from the stream! + auto* FileDataPtr = reinterpret_cast<Char*>( pFileData->GetDataPtr() ); + auto Size = pFileData->GetSize(); + ShaderSource.append( FileDataPtr, FileDataPtr + Size/sizeof(*FileDataPtr) ); + } + + const D3D_SHADER_MACRO *pDefines = nullptr; + std::vector<D3D_SHADER_MACRO> D3DMacros; + if( ShaderCreationAttribs.Macros ) + { + for( auto* pCurrMacro = ShaderCreationAttribs.Macros; pCurrMacro->Name && pCurrMacro->Definition; ++pCurrMacro ) + { + D3DMacros.push_back( {pCurrMacro->Name, pCurrMacro->Definition} ); + } + D3DMacros.push_back( {nullptr, nullptr} ); + pDefines = D3DMacros.data(); + } + + CHECK_D3D_RESULT_THROW( CompileShader( ShaderSource.c_str(), ShaderCreationAttribs.EntryPoint, pDefines, ShaderCreationAttribs.pShaderSourceStreamFactory, strShaderProfile.c_str(), &m_pShaderByteCode ), + "Failed to compile the shader"); + + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + switch(ShaderCreationAttribs.Desc.ShaderType) + { + +#define CREATE_SHADER(SHADER_NAME, ShaderName)\ + case SHADER_TYPE_##SHADER_NAME: \ + { \ + ID3D11##ShaderName##Shader *pShader; \ + HRESULT hr = pDeviceD3D11->Create##ShaderName##Shader( m_pShaderByteCode->GetBufferPointer(), m_pShaderByteCode->GetBufferSize(), NULL, &pShader ); \ + CHECK_D3D_RESULT_THROW( hr, "Failed to create D3D11 shader" ); \ + if( SUCCEEDED(hr) ) \ + { \ + pShader->QueryInterface( __uuidof(ID3D11DeviceChild), reinterpret_cast<void**>( static_cast<ID3D11DeviceChild**>(&m_pShader) ) ); \ + pShader->Release(); \ + } \ + break; \ + } + + CREATE_SHADER(VERTEX, Vertex) + CREATE_SHADER(PIXEL, Pixel) + CREATE_SHADER(GEOMETRY, Geometry) + CREATE_SHADER(DOMAIN, Domain) + CREATE_SHADER(HULL, Hull) + CREATE_SHADER(COMPUTE, Compute) + + default: UNEXPECTED( "Unknown shader type" ); + } + + if(!m_pShader) + LOG_ERROR_AND_THROW("Failed to create the shader from the byte code"); + + LoadShaderResources(); + + // Byte code is only required for the vertex shader to create input layout + if( ShaderCreationAttribs.Desc.ShaderType != SHADER_TYPE_VERTEX ) + m_pShaderByteCode.Release(); +} + +ShaderD3D11Impl::~ShaderD3D11Impl() +{ +} + +#define LOG_RESORUCE_BINDING_ERROR(ResType, pResource, VarName, ShaderName, ...)\ +{ \ + const auto &ResName = pResource->GetDesc().Name; \ + LOG_ERROR_MESSAGE( "Failed to bind ", ResType, " \"", ResName, "\" to variable \"", VarName, \ + "\" in shader \"", ShaderName, "\". ", __VA_ARGS__ ); \ +} + +void ShaderD3D11Impl::BindConstantBuffers( IResourceMapping* pResourceMapping, Uint32 Flags ) +{ + if( !pResourceMapping ) + { + LOG_ERROR_MESSAGE( "Failed to bind constant buffers in shader \"", m_Desc.Name ? m_Desc.Name : "", "\": resource mapping is null" ); + return; + } + // Bind constant buffers + if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) + { + m_BoundCBs.clear(); + } + for( auto it = m_ConstanBuffers.begin(); it != m_ConstanBuffers.end(); ++it ) + { + if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && it->IsBound() ) + continue; + + RefCntAutoPtr<IDeviceObject> pBuffer; + if( pResourceMapping ) + pResourceMapping->GetResource( it->Name.c_str(), &pBuffer ); + if( pBuffer ) + { + it->Set( pBuffer ); + } + else + { + if( (Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED) && !it->IsBound() ) + LOG_ERROR_MESSAGE("Cannot bind resource to shader variable \"", it->Name, "\": resource not found in the resource mapping") + continue; + } + } +} + + +void ShaderD3D11Impl::ConstBuffBindInfo::Set( IDeviceObject *pBuffer ) +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + auto &BoundCBs = pShaderD3D11->m_BoundCBs; + if( BoundCBs.size() <= BindPoint ) + BoundCBs.resize( BindPoint + 1 ); + + if( pBuffer ) + { + RefCntAutoPtr<IBufferD3D11> pBuffD3D11; + pBuffer->QueryInterface( IID_BufferD3D11, reinterpret_cast<IObject**>(static_cast<IBufferD3D11**>(&pBuffD3D11)) ); + if( pBuffD3D11 ) + { + if( pBuffD3D11->GetDesc().BindFlags & BIND_UNIFORM_BUFFER ) + { + BoundCBs[BindPoint].pd3d11Buff = pBuffD3D11->GetD3D11Buffer(); + VERIFY(BoundCBs[BindPoint].pd3d11Buff, "No relevant D3D11 buffer") + BoundCBs[BindPoint].pBuff = pBuffD3D11; + } + else + { + LOG_RESORUCE_BINDING_ERROR("buffer", pBuffer, Name, pShaderD3D11->m_Desc.Name, "Buffer was not created with BIND_UNIFORM_BUFFER flag.") + } + } + else + { + LOG_RESORUCE_BINDING_ERROR("buffer", pBuffer, Name, pShaderD3D11->m_Desc.Name, "Incorrect resource type: buffer is expected.") + } + } + else + { + BoundCBs[BindPoint] = BoundCB(); + } +} + +bool ShaderD3D11Impl::ConstBuffBindInfo::IsBound() +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + auto &BoundCBs = pShaderD3D11->m_BoundCBs; + if( BindPoint < BoundCBs.size() && BoundCBs[BindPoint].pd3d11Buff != nullptr ) + { + VERIFY(BoundCBs[BindPoint].pBuff != nullptr, "No relevant buffer resource") + return true; + } + + return false; +} + +template<typename TResourceViewType> +struct ResourceViewTraits{}; + +template<> +struct ResourceViewTraits<ITextureViewD3D11> +{ + static const Char *Name; +}; +const Char *ResourceViewTraits<ITextureViewD3D11>::Name = "texture view"; + +template<> +struct ResourceViewTraits<IBufferViewD3D11> +{ + static const Char *Name; +}; +const Char *ResourceViewTraits<IBufferViewD3D11>::Name = "buffer view"; + +// Helper template class that facilitates binding SRVs and UAVs +class BindViewHelper +{ +public: + BindViewHelper(IResourceMapping *pRM, Uint32 Fl) : + pResourceMapping(pRM), + Flags(Fl) + {} + + template<typename IterType> + void Bind( IterType &pShaderVar) + { + if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && pShaderVar->IsBound() ) + return; + + const auto& VarName = pShaderVar->GetName(); + RefCntAutoPtr<IDeviceObject> pView; + if( pResourceMapping ) + pResourceMapping->GetResource( VarName.c_str(), &pView ); + if( pView ) + { + pShaderVar->Set(pView); + } + else + { + if( (Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED) && !pShaderVar->IsBound() ) + LOG_ERROR_MESSAGE( "Cannot bind resource to shader variable \"", VarName, "\": resource view not found in the resource mapping" ) + return; + } + } + +private: + IResourceMapping* const pResourceMapping; + const Uint32 Flags; +}; + +// Helper template function to facilitate setting shader variables +// of different types +template<typename TResourceViewType, ///< Type of the view (ITextureViewD3D11 or IBufferViewD3D11) + typename TD3D11ViewType, ///< Type of the D3D11 view (ID3D11ShaderResourceView or ID3D11UnorderedAccessView) + typename TBoundViewType, ///< Type of the bound view data array element (BoundSRV or BoundUAV) + typename TGetResourceMethodType, ///< Type of the method to get resource from the view (ITextureViewD3D11::GetTexture or IBufferViewD3D11::GetBuffer) + typename TBindSamplerProcType, ///< Type of the procedure to set samplers + typename TViewTypeEnum> ///< Type of the expected view enum +void SetShaderVariableHelper(IDeviceObject *pView, + std::vector<TBoundViewType> &ViewArray, + UINT BindPoint, + const String& VarName, + TGetResourceMethodType GetResourceMethod, + const Diligent::INTERFACE_ID ViewID, + typename TViewTypeEnum ExpectedViewType, + const String& ShaderName, + TBindSamplerProcType BindSamplerProc) +{ + if( ViewArray.size() <= BindPoint ) + ViewArray.resize( BindPoint + 1 ); + if( pView ) + { + RefCntAutoPtr<TResourceViewType> pViewD3D11; + pView->QueryInterface( ViewID, reinterpret_cast<IObject**>(static_cast<TResourceViewType**>(&pViewD3D11)) ); + if( pViewD3D11 ) + { + auto ViewType = pViewD3D11->GetDesc().ViewType; + if( ViewType == ExpectedViewType ) + { + auto &BoundView = ViewArray[BindPoint]; + BoundView.pd3d11View = static_cast<TD3D11ViewType*>( pViewD3D11->GetD3D11View() ); + VERIFY(BoundView.pd3d11View, "No relevant D3D11 view") + BoundView.pView = pViewD3D11; + BoundView.pResource = (pViewD3D11->*GetResourceMethod)(); + VERIFY(BoundView.pResource, "No relevant resource") + BindSamplerProc(pViewD3D11); + } + else + { + const auto *ExpectedViewTypeName = GetViewTypeLiteralName( ExpectedViewType ); + const auto *ActualViewTypeName = GetViewTypeLiteralName( ViewType ); + LOG_RESORUCE_BINDING_ERROR(ResourceViewTraits<TResourceViewType>::Name, pViewD3D11, VarName, ShaderName, + "Incorrect view type: ", ExpectedViewTypeName, " is expected, ", ActualViewTypeName, " provided." ); + } + } + else + { + LOG_RESORUCE_BINDING_ERROR("resource", pView, VarName, ShaderName, "Incorect resource type: ", ResourceViewTraits<TResourceViewType>::Name, " is expected.") + } + } + else + { + ViewArray[BindPoint] = TBoundViewType(); + BindSamplerProc(nullptr); + } +} + +void ShaderD3D11Impl::TexAndSamplerBindInfo::Set( IDeviceObject *pView ) +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + SetShaderVariableHelper<ITextureViewD3D11, ID3D11ShaderResourceView>(pView, pShaderD3D11->m_BoundSRVs, BindPoint, Name, + &ITextureViewD3D11::GetTexture, IID_TextureViewD3D11, TEXTURE_VIEW_SHADER_RESOURCE, + pShaderD3D11->m_Desc.Name, + [&]( ITextureViewD3D11 *pTexViewD3D11 ) + { + if( SamplerBindPoint != InvalidBindPoint ) + { + auto &BoundSamplers = pShaderD3D11->m_BoundSamplers; + if( BoundSamplers.size() <= SamplerBindPoint ) + BoundSamplers.resize( SamplerBindPoint + 1 ); + auto &BndSam = BoundSamplers[SamplerBindPoint]; + if( pTexViewD3D11 ) + { + auto pSampler = pTexViewD3D11->GetSampler(); + if( pSampler ) + { + BndSam.pd3d11Sampler = ValidatedCast<SamplerD3D11Impl>(pSampler)->m_pd3dSampler; + VERIFY(BndSam.pd3d11Sampler, "No relevant D3D11 sampler") + BndSam.pSampler = pSampler; + } + else + { + LOG_ERROR_MESSAGE( "Failed to bind sampler to variable \"", SamplerName, ". Sampler is not set in the texture view \"", pTexViewD3D11->GetDesc().Name, "\"" ); + } + } + else + { + BndSam = BoundSampler(); + } + } + } + ); + +} + +void ShaderD3D11Impl::BuffSRVBindInfo::Set( IDeviceObject *pView ) +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + SetShaderVariableHelper<IBufferViewD3D11, ID3D11ShaderResourceView>(pView, pShaderD3D11->m_BoundSRVs, BindPoint, Name, + &IBufferViewD3D11::GetBuffer, IID_BufferViewD3D11, BUFFER_VIEW_SHADER_RESOURCE, + pShaderD3D11->m_Desc.Name, + []( IBufferViewD3D11 * ){} + ); +} + +void ShaderD3D11Impl::TexUAVBindInfo::Set( IDeviceObject *pView ) +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + SetShaderVariableHelper<ITextureViewD3D11, ID3D11UnorderedAccessView>( + pView, pShaderD3D11->m_BoundUAVs, BindPoint, Name, + &ITextureViewD3D11::GetTexture, IID_TextureViewD3D11, TEXTURE_VIEW_UNORDERED_ACCESS, + pShaderD3D11->m_Desc.Name, + []( ITextureViewD3D11 * ){} + ); +} + +void ShaderD3D11Impl::BuffUAVBindInfo::Set( IDeviceObject *pView ) +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + SetShaderVariableHelper<IBufferViewD3D11, ID3D11UnorderedAccessView>(pView, pShaderD3D11->m_BoundUAVs, BindPoint, Name, + &IBufferViewD3D11::GetBuffer, IID_BufferViewD3D11, BUFFER_VIEW_UNORDERED_ACCESS, + pShaderD3D11->m_Desc.Name, + []( IBufferViewD3D11 * ){} + ); +} + +template<typename TBoundViewType> +bool CheckBoundResource(const std::vector<TBoundViewType> &ViewArray, UINT BindPoint) +{ + if( BindPoint < ViewArray.size() && ViewArray[BindPoint].pd3d11View != nullptr ) + { + VERIFY(ViewArray[BindPoint].pResource != nullptr, "No relevant resource") + VERIFY(ViewArray[BindPoint].pView != nullptr, "No relevant resource view") + return true; + } + return false; +} + +bool ShaderD3D11Impl::TexAndSamplerBindInfo::IsBound() +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + return CheckBoundResource( pShaderD3D11->m_BoundSRVs, BindPoint ); +} + +bool ShaderD3D11Impl::BuffSRVBindInfo::IsBound() +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + return CheckBoundResource( pShaderD3D11->m_BoundSRVs, BindPoint ); +} + +bool ShaderD3D11Impl::UAVBindInfoBase::IsBound() +{ + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); + return CheckBoundResource( pShaderD3D11->m_BoundUAVs, BindPoint ); +} + +void ShaderD3D11Impl::BindSRVsAndSamplers(IResourceMapping* pResourceMapping, Uint32 Flags ) +{ + if( !pResourceMapping ) + { + LOG_ERROR_MESSAGE( "Failed to bind SRVs and samplers in shader \"", m_Desc.Name ? m_Desc.Name : "", "\": resource mapping is null" ); + return; + } + + if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) + { + m_BoundSRVs.clear(); + m_BoundSamplers.clear(); + } + + BindViewHelper BindSRVHelper(pResourceMapping, Flags); + + for( auto it = m_TexAndSamplers.begin(); it != m_TexAndSamplers.end(); ++it ) + { + BindSRVHelper.Bind(it); + } + + for( auto it = m_BuffSRVs.begin(); it != m_BuffSRVs.end(); ++it ) + { + BindSRVHelper.Bind(it); + } +} + +void ShaderD3D11Impl::BindUAVs( IResourceMapping* pResourceMapping, Uint32 Flags ) +{ + if( !pResourceMapping ) + { + LOG_ERROR_MESSAGE( "Failed to bind UAVs in shader \"", m_Desc.Name ? m_Desc.Name : "", "\": resource mapping is null" ); + return; + } + + // Bind constant buffers + if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) + { + m_BoundUAVs.clear(); + } + + BindViewHelper BindUAVHelper(pResourceMapping, Flags); + + for( auto it = m_TexUAVs.begin(); it != m_TexUAVs.end(); ++it ) + { + BindUAVHelper.Bind(it); + } + + for( auto it = m_BuffUAVs.begin(); it != m_BuffUAVs.end(); ++it ) + { + BindUAVHelper.Bind(it); + } +} + +void ShaderD3D11Impl::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags ) +{ + if( !pResourceMapping ) + { + LOG_ERROR_MESSAGE( "Failed to bind resources in shader \"", m_Desc.Name ? m_Desc.Name : "", "\": resource mapping is null" ); + return; + } + + BindConstantBuffers( pResourceMapping, Flags ); + BindSRVsAndSamplers( pResourceMapping, Flags ); + BindUAVs(pResourceMapping, Flags ); +} + +IShaderVariable* ShaderD3D11Impl::GetShaderVariable( const Char* Name ) +{ + // Name will be implicitly converted to HashMapStringKey without making a copy + auto it = m_VariableHash.find( Name ); + if( it == m_VariableHash.end() ) + { + LOG_ERROR_MESSAGE( "Shader variable \"", Name, "\" is not found in shader \"", m_Desc.Name ? m_Desc.Name : "", "\". Attempts to set the variable will be silently ignored." ); + return &m_DummyShaderVar; + } + return it->second; +} + + + +IMPLEMENT_QUERY_INTERFACE( ShaderD3D11Impl, IID_ShaderD3D11, TShaderBase ) + +#ifdef VERIFY_SHADER_BINDINGS +void ShaderD3D11Impl::dbgVerifyBindings() +{ + const auto *ShaderName = m_Desc.Name ? m_Desc.Name : ""; +#define LOG_MISSING_BINDING(VarType, Name)\ + LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", Name, "\" in shader \"", ShaderName, "\"" ); + + for( auto cb = m_ConstanBuffers.begin(); cb != m_ConstanBuffers.end(); ++cb ) + { + if( m_BoundCBs.size() <= cb->BindPoint || m_BoundCBs[cb->BindPoint].pd3d11Buff == nullptr ) + LOG_MISSING_BINDING("constant buffer", cb->Name) + } + + for( auto tex = m_TexAndSamplers.begin(); tex != m_TexAndSamplers.end(); ++tex ) + { + if( m_BoundSRVs.size() <= tex->BindPoint || m_BoundSRVs[tex->BindPoint].pd3d11View == nullptr ) + LOG_MISSING_BINDING("texture", tex->Name) + + if( tex->SamplerBindPoint != InvalidBindPoint && + (m_BoundSamplers.size() <= tex->SamplerBindPoint || m_BoundSamplers[tex->SamplerBindPoint].pd3d11Sampler == nullptr) ) + LOG_MISSING_BINDING("sampler", tex->SamplerName) + } + + for( auto buf = m_BuffSRVs.begin(); buf != m_BuffSRVs.end(); ++buf ) + { + if( m_BoundSRVs.size() <= buf->BindPoint || m_BoundSRVs[buf->BindPoint].pd3d11View == nullptr ) + LOG_MISSING_BINDING("buffer", buf->Name) + } + + for( auto uav = m_TexUAVs.begin(); uav != m_TexUAVs.end(); ++uav ) + { + if( m_BoundUAVs.size() <= uav->BindPoint || m_BoundUAVs[uav->BindPoint].pd3d11View == nullptr ) + LOG_MISSING_BINDING("texture UAV", uav->Name) + } + + for( auto uav = m_BuffUAVs.begin(); uav != m_BuffUAVs.end(); ++uav ) + { + if( m_BoundUAVs.size() <= uav->BindPoint || m_BoundUAVs[uav->BindPoint].pd3d11View == nullptr ) + LOG_MISSING_BINDING("buffer UAV", uav->Name) + } +} +#endif + +} diff --git a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp new file mode 100644 index 00000000..d2f639a6 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp @@ -0,0 +1,254 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "SwapChainD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" +#include "DeviceContextD3D11Impl.h" + +using namespace Diligent; + +namespace Diligent +{ + +SwapChainD3D11Impl::SwapChainD3D11Impl(const SwapChainDesc& SCDesc, + RenderDeviceD3D11Impl* pRenderDeviceD3D11, + DeviceContextD3D11Impl* pDeviceContextD3D11, + void* pNativeWndHandle) : + TSwapChainBase(pRenderDeviceD3D11, pDeviceContextD3D11, SCDesc) +{ + auto *pDevice = pRenderDeviceD3D11->GetD3D11Device(); + + auto DXGIColorBuffFmt = TexFormatToDXGI_Format(m_SwapChainDesc.ColorBufferFormat); + +#if defined( PLATFORM_WINDOWS ) + + auto hWnd = reinterpret_cast<HWND>(pNativeWndHandle); + + if( m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0 ) + { + RECT rc; + GetClientRect( hWnd, &rc ); + m_SwapChainDesc.Width = rc.right - rc.left; + m_SwapChainDesc.Height = rc.bottom - rc.top; + } + + // This sequence obtains the DXGI factory that was used to create the Direct3D device above. + CComPtr<IDXGIDevice> pDXGIDevice; + pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>( static_cast<IDXGIDevice**>(&pDXGIDevice) ) ); + CComPtr<IDXGIAdapter> pDXGIAdapter; + pDXGIDevice->GetAdapter(&pDXGIAdapter); + CComPtr<IDXGIFactory> pDXGIFactory; + pDXGIAdapter->GetParent(__uuidof(pDXGIFactory), reinterpret_cast<void**>( static_cast<IDXGIFactory**>(&pDXGIFactory) )); + + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory( &sd, sizeof( sd ) ); + sd.BufferCount = 1; + sd.BufferDesc.Width = m_SwapChainDesc.Width; + sd.BufferDesc.Height = m_SwapChainDesc.Height; + sd.BufferDesc.Format = DXGIColorBuffFmt; + sd.BufferDesc.RefreshRate.Numerator = 0; + sd.BufferDesc.RefreshRate.Denominator = 0; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.OutputWindow = hWnd; + sd.SampleDesc.Count = m_SwapChainDesc.SamplesCount; + sd.SampleDesc.Quality = 0; + sd.Windowed = TRUE; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // Set this flag to enable an application to switch + // modes by calling IDXGISwapChain::ResizeTarget. When switching from windowed to full-screen mode, the + // display mode (or monitor resolution) will be changed to match the dimensions of the application window. + CHECK_D3D_RESULT_THROW( pDXGIFactory->CreateSwapChain(pDevice, &sd, &m_pSwapChain), + "Failed to create DXGI swap chain" ); + +#elif defined( PLATFORM_WINDOWS_STORE ) + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; + + swapChainDesc.Width = m_SwapChainDesc.Width; + swapChainDesc.Height = m_SwapChainDesc.Height; + swapChainDesc.Format = DXGIColorBuffFmt; + swapChainDesc.Stereo = false; + swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling. + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency. + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. + swapChainDesc.Flags = 0; + swapChainDesc.Scaling = DXGI_SCALING_NONE; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + + CComPtr<IDXGIDevice3> pDXGIDevice; + pDevice->QueryInterface(__uuidof(IDXGIDevice3), reinterpret_cast<void**>(static_cast<IDXGIDevice3**>(&pDXGIDevice))); + CComPtr<IDXGIAdapter> pDXGIAdapter; + pDXGIDevice->GetAdapter(&pDXGIAdapter); + CComPtr<IDXGIFactory2> pDXGIFactory; + pDXGIAdapter->GetParent(__uuidof(pDXGIFactory), reinterpret_cast<void**>(static_cast<IDXGIFactory2**>(&pDXGIFactory))); + + CComPtr<IDXGISwapChain1> pSwapChain1; + HRESULT hr = pDXGIFactory->CreateSwapChainForCoreWindow( + pDevice, + reinterpret_cast<IUnknown*>(pNativeWndHandle), + &swapChainDesc, + nullptr, + &pSwapChain1); + CHECK_D3D_RESULT_THROW( hr, "Failed to create DXGI swap chain" ); + + pSwapChain1->QueryInterface( __uuidof(m_pSwapChain), reinterpret_cast<void**>(static_cast<IDXGISwapChain**>(&m_pSwapChain)) ); + + // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and + // ensures that the application will only render after each VSync, minimizing power consumption. + pDXGIDevice->SetMaximumFrameLatency( 1 ); + +#endif + + CreateRTVandDSV(); +} + +SwapChainD3D11Impl::~SwapChainD3D11Impl() +{ + +} + +void SwapChainD3D11Impl::CreateRTVandDSV() +{ + auto *pDevice = ValidatedCast<RenderDeviceD3D11Impl>(m_pRenderDevice.RawPtr())->GetD3D11Device(); + + m_pRenderTargetView.Release(); + m_pDepthStencilView.Release(); + + // Create a render target view + CComPtr<ID3D11Texture2D> pBackBuffer; + CHECK_D3D_RESULT_THROW( m_pSwapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>( static_cast<ID3D11Texture2D**>(&pBackBuffer) ) ), + "Failed to get back buffer from swap chain" ); + + CHECK_D3D_RESULT_THROW( pDevice->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderTargetView ), + "Failed to get RTV for the back buffer" ); + + // Create depth buffer + D3D11_TEXTURE2D_DESC DepthBufferDesc; + DepthBufferDesc.Width = m_SwapChainDesc.Width; + DepthBufferDesc.Height = m_SwapChainDesc.Height; + DepthBufferDesc.MipLevels = 1; + DepthBufferDesc.ArraySize = 1; + auto DepthFormat = TexFormatToDXGI_Format( m_SwapChainDesc.DepthBufferFormat ); + DepthBufferDesc.Format = DepthFormat; + DepthBufferDesc.SampleDesc.Count = m_SwapChainDesc.SamplesCount; + DepthBufferDesc.SampleDesc.Quality = 0; + DepthBufferDesc.Usage = D3D11_USAGE_DEFAULT; + DepthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + DepthBufferDesc.CPUAccessFlags = 0; + DepthBufferDesc.MiscFlags = 0; + CComPtr<ID3D11Texture2D> ptex2DDepthBuffer; + CHECK_D3D_RESULT_THROW( pDevice->CreateTexture2D( &DepthBufferDesc, NULL, &ptex2DDepthBuffer ), + "Failed to create the depth buffer" ); + + // Create DSV + CHECK_D3D_RESULT_THROW( pDevice->CreateDepthStencilView( ptex2DDepthBuffer, NULL, &m_pDepthStencilView ), + "Failed to create the DSV for the depth buffer" ); +} + +IMPLEMENT_QUERY_INTERFACE( SwapChainD3D11Impl, IID_SwapChainD3D11, TSwapChainBase ) + +void SwapChainD3D11Impl::Present() +{ + UINT SyncInterval = 0; +#ifdef PLATFORM_WINDOWS_STORE + SyncInterval = 1; // Interval 0 is not supported on Windows Phone +#endif + + auto pDeviceContext = m_wpDeviceContext.Lock(); + if( !pDeviceContext ) + { + LOG_ERROR_MESSAGE( "Immediate context has been released" ); + return; + } + + auto *pImmediateCtx = pDeviceContext.RawPtr(); + auto *pImmediateCtxD3D11 = ValidatedCast<DeviceContextD3D11Impl>( pImmediateCtx ); + // Clear the state caches to release all outstanding objects + // that are only kept alive by references in the cache + // It is better to do this before calling Present() as D3D11 + // also releases resources during present. + pImmediateCtxD3D11->ClearShaderStateCache(); + + m_pSwapChain->Present( SyncInterval, 0 ); + +#ifdef PLATFORM_WINDOWS_STORE + // A successful Present call for DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL SwapChains unbinds + // backbuffer 0 from all GPU writeable bind points. + // We need to rebind all render targets to make sure that + // the back buffer is not unbound + pImmediateCtxD3D11->RebindRenderTargets(); +#endif +} + +void SwapChainD3D11Impl::Resize( Uint32 NewWidth, Uint32 NewHeight ) +{ + if( TSwapChainBase::Resize(NewWidth, NewHeight) ) + { + auto pDeviceContext = m_wpDeviceContext.Lock(); + VERIFY( pDeviceContext, "Immediate context has been released" ); + if( pDeviceContext ) + { + auto *pImmediateCtxD3D11 = ValidatedCast<DeviceContextD3D11Impl>(pDeviceContext.RawPtr()); + bool bIsDefaultFBBound = pImmediateCtxD3D11->IsDefaultFBBound(); + if( bIsDefaultFBBound ) + { + ITextureView *pNullTexView[] = { nullptr }; + pImmediateCtxD3D11->SetRenderTargets( _countof( pNullTexView ), pNullTexView, nullptr ); + } + + // Swap chain cannot be resized until all references are released + m_pRenderTargetView.Release(); + m_pDepthStencilView.Release(); + + try + { + DXGI_SWAP_CHAIN_DESC SCDes; + memset( &SCDes, 0, sizeof( SCDes ) ); + m_pSwapChain->GetDesc( &SCDes ); + CHECK_D3D_RESULT_THROW( m_pSwapChain->ResizeBuffers(SCDes.BufferCount, m_SwapChainDesc.Width, + m_SwapChainDesc.Height, SCDes.BufferDesc.Format, + SCDes.Flags), + "Failed to resize the DXGI swap chain" ); + + + CreateRTVandDSV(); + + if( bIsDefaultFBBound ) + { + // Set default render target and viewport + pImmediateCtxD3D11->SetRenderTargets( 0, nullptr, nullptr ); + pImmediateCtxD3D11->SetViewports( 1, nullptr, 0, 0 ); + } + } + catch( const std::runtime_error & ) + { + LOG_ERROR( "Failed to resize the swap chain" ); + } + } + } +} + + +} diff --git a/Graphics/GraphicsEngineD3D11/src/Texture1D_D3D11.cpp b/Graphics/GraphicsEngineD3D11/src/Texture1D_D3D11.cpp new file mode 100644 index 00000000..75eaab86 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/Texture1D_D3D11.cpp @@ -0,0 +1,226 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "Texture1D_D3D11.h" +#include "RenderDeviceD3D11Impl.h" +#include "D3D11TypeConversions.h" + +namespace Diligent +{ + +Texture1D_D3D11 :: Texture1D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : + TextureBaseD3D11(pRenderDeviceD3D11, TexDesc, InitData) +{ + auto D3D11TexFormat = TexFormatToDXGI_Format(m_Desc.Format, m_Desc.BindFlags); + auto D3D11BindFlags = BindFlagsToD3D11BindFlags(m_Desc.BindFlags); + auto D3D11CPUAccessFlags = CPUAccessFlagsToD3D11CPUAccessFlags(m_Desc.CPUAccessFlags); + auto D3D11Usage = UsageToD3D11Usage(m_Desc.Usage); + UINT MiscFlags = MiscTextureFlagsToD3D11Flags(m_Desc.MiscFlags); + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + + D3D11_TEXTURE1D_DESC Tex1DDesc = + { + m_Desc.Width, + m_Desc.MipLevels, + m_Desc.ArraySize, + D3D11TexFormat, + D3D11Usage, + D3D11BindFlags, + D3D11CPUAccessFlags, + MiscFlags + }; + + std::vector<D3D11_SUBRESOURCE_DATA> D3D11InitData; + PrepareD3D11InitData(InitData, Tex1DDesc.ArraySize * Tex1DDesc.MipLevels, D3D11InitData); + + ID3D11Texture1D *ptex1D = nullptr; + HRESULT hr = pDeviceD3D11->CreateTexture1D(&Tex1DDesc, D3D11InitData.size() ? D3D11InitData.data() : nullptr, &ptex1D); + m_pd3d11Texture.Attach(ptex1D); + CHECK_D3D_RESULT_THROW( hr, "Failed to create the Direct3D11 Texture1D" ); +} + +Texture1D_D3D11 :: ~Texture1D_D3D11() +{ +} + +void Texture1D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ) +{ + VERIFY( ppD3D11SRV && *ppD3D11SRV == nullptr, "SRV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( SRVDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); + if( !(SRVDesc.TextureType == TEXTURE_TYPE_1D || SRVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY) ) + LOG_ERROR_AND_THROW( "Unsupported texture type. Only TEXTURE_TYPE_1D or TEXTURE_TYPE_1D_ARRAY is allowed" ); + + if( SRVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + SRVDesc.Format = m_Desc.Format; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; + memset(&D3D11_SRVDesc, 0, sizeof(D3D11_SRVDesc)); + D3D11_SRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); + + if( SRVDesc.TextureType == TEXTURE_TYPE_1D ) + { + D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + D3D11_SRVDesc.Texture1D.MipLevels = SRVDesc.NumMipLevels; + D3D11_SRVDesc.Texture1D.MostDetailedMip = SRVDesc.MostDetailedMip; + } + else if( SRVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) + { + D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + D3D11_SRVDesc.Texture1DArray.ArraySize = SRVDesc.NumArraySlices; + D3D11_SRVDesc.Texture1DArray.FirstArraySlice = SRVDesc.FirstArraySlice; + D3D11_SRVDesc.Texture1DArray.MipLevels = SRVDesc.NumMipLevels; + D3D11_SRVDesc.Texture1DArray.MostDetailedMip = SRVDesc.MostDetailedMip; + } + else + { + UNEXPECTED( "Unexpected view type" ); + } + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Texture, &D3D11_SRVDesc, ppD3D11SRV ), + "Failed to create D3D11 shader resource view"); +} + +void Texture1D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ) +{ + VERIFY( ppD3D11RTV && *ppD3D11RTV == nullptr, "RTV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( RTVDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); + if( !(RTVDesc.TextureType == TEXTURE_TYPE_1D || RTVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) ) + LOG_ERROR_AND_THROW( "Unsupported texture type. Only TEXTURE_TYPE_1D or TEXTURE_TYPE_1D_ARRAY is allowed" ); + + if( RTVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + RTVDesc.Format = m_Desc.Format; + } + + D3D11_RENDER_TARGET_VIEW_DESC D3D11_RTVDesc; + memset(&D3D11_RTVDesc, 0, sizeof(D3D11_RTVDesc)); + D3D11_RTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); + + if( RTVDesc.TextureType == TEXTURE_TYPE_1D ) + { + D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; + D3D11_RTVDesc.Texture1D.MipSlice = RTVDesc.MostDetailedMip; + } + else if( RTVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) + { + D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; + D3D11_RTVDesc.Texture1DArray.ArraySize = RTVDesc.NumArraySlices; + D3D11_RTVDesc.Texture1DArray.FirstArraySlice = RTVDesc.FirstArraySlice; + D3D11_RTVDesc.Texture1DArray.MipSlice = RTVDesc.MostDetailedMip; + } + else + { + UNEXPECTED( "Unexpected view type" ); + } + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRenderTargetView( m_pd3d11Texture, &D3D11_RTVDesc, ppD3D11RTV ), + "Failed to create D3D11 render target view"); +} + +void Texture1D_D3D11::CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ) +{ + VERIFY( ppD3D11DSV && *ppD3D11DSV == nullptr, "DSV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( DSVDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); + if( !(DSVDesc.TextureType == TEXTURE_TYPE_1D || DSVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY) ) + LOG_ERROR_AND_THROW("Unsupported texture type. Only TEXTURE_TYPE_1D or TEXTURE_TYPE_1D_ARRAY is allowed"); + + if( DSVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + DSVDesc.Format = m_Desc.Format; + } + + D3D11_DEPTH_STENCIL_VIEW_DESC D3D11_DSVDesc; + memset(&D3D11_DSVDesc, 0, sizeof(D3D11_DSVDesc)); + D3D11_DSVDesc.Format = TexFormatToDXGI_Format(DSVDesc.Format, BIND_DEPTH_STENCIL); + + if( DSVDesc.TextureType == TEXTURE_TYPE_1D ) + { + D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; + D3D11_DSVDesc.Texture1D.MipSlice = DSVDesc.MostDetailedMip; + } + else if( DSVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) + { + D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY; + D3D11_DSVDesc.Texture1DArray.ArraySize = DSVDesc.NumArraySlices; + D3D11_DSVDesc.Texture1DArray.FirstArraySlice = DSVDesc.FirstArraySlice; + D3D11_DSVDesc.Texture1DArray.MipSlice = DSVDesc.MostDetailedMip; + } + else + { + UNEXPECTED( "Unexpected view type" ); + } + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateDepthStencilView( m_pd3d11Texture, &D3D11_DSVDesc, ppD3D11DSV ), + "Failed to create D3D11 depth stencil view"); +} + +void Texture1D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ) +{ + VERIFY( ppD3D11UAV && *ppD3D11UAV == nullptr, "UAV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( UAVDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); + if( !(UAVDesc.TextureType == TEXTURE_TYPE_1D || UAVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY) ) + LOG_ERROR_AND_THROW("Unsupported texture type. Only TEXTURE_TYPE_1D or TEXTURE_TYPE_1D_ARRAY is allowed"); + + if( UAVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + UAVDesc.Format = m_Desc.Format; + } + + D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; + memset(&D3D11_UAVDesc, 0, sizeof(D3D11_UAVDesc)); + D3D11_UAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); + + if( UAVDesc.TextureType == TEXTURE_TYPE_1D ) + { + D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D; + D3D11_UAVDesc.Texture1D.MipSlice = UAVDesc.MostDetailedMip; + } + else if( UAVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) + { + D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY; + D3D11_UAVDesc.Texture1DArray.ArraySize = UAVDesc.NumArraySlices; + D3D11_UAVDesc.Texture1DArray.FirstArraySlice = UAVDesc.FirstArraySlice; + D3D11_UAVDesc.Texture1DArray.MipSlice = UAVDesc.MostDetailedMip; + } + else + { + UNEXPECTED( "Unexpected view type" ); + } + + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Texture, &D3D11_UAVDesc, ppD3D11UAV ), + "Failed to create D3D11 unordered access view"); +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/Texture2D_D3D11.cpp b/Graphics/GraphicsEngineD3D11/src/Texture2D_D3D11.cpp new file mode 100644 index 00000000..fc34d18d --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/Texture2D_D3D11.cpp @@ -0,0 +1,284 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "Texture2D_D3D11.h" +#include "RenderDeviceD3D11Impl.h" +#include "D3D11TypeConversions.h" + +namespace Diligent +{ + +Texture2D_D3D11 :: Texture2D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : + TextureBaseD3D11(pRenderDeviceD3D11, TexDesc, InitData) +{ + auto D3D11TexFormat = TexFormatToDXGI_Format(m_Desc.Format, m_Desc.BindFlags); + auto D3D11BindFlags = BindFlagsToD3D11BindFlags(m_Desc.BindFlags); + auto D3D11CPUAccessFlags = CPUAccessFlagsToD3D11CPUAccessFlags(m_Desc.CPUAccessFlags); + auto D3D11Usage = UsageToD3D11Usage(m_Desc.Usage); + UINT MiscFlags = MiscTextureFlagsToD3D11Flags(m_Desc.MiscFlags); + DXGI_SAMPLE_DESC D3D11SampleDesc = {m_Desc.SampleCount, 0}; + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + + D3D11_TEXTURE2D_DESC Tex2DDesc = + { + m_Desc.Width, + m_Desc.Height, + m_Desc.MipLevels, + m_Desc.ArraySize, + D3D11TexFormat, + D3D11SampleDesc, + D3D11Usage, + D3D11BindFlags, + D3D11CPUAccessFlags, + MiscFlags + }; + + std::vector<D3D11_SUBRESOURCE_DATA> D3D11InitData; + PrepareD3D11InitData(InitData, Tex2DDesc.ArraySize * Tex2DDesc.MipLevels, D3D11InitData); + + ID3D11Texture2D *ptex2D = nullptr; + HRESULT hr = pDeviceD3D11->CreateTexture2D(&Tex2DDesc, D3D11InitData.size() ? D3D11InitData.data() : nullptr, &ptex2D); + m_pd3d11Texture.Attach(ptex2D); + CHECK_D3D_RESULT_THROW( hr, "Failed to create the Direct3D11 Texture2D" ); +} + +Texture2D_D3D11 :: ~Texture2D_D3D11() +{ +} + +void Texture2D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ) +{ + VERIFY( ppD3D11SRV && *ppD3D11SRV == nullptr, "SRV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( SRVDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); + if( !(SRVDesc.TextureType == TEXTURE_TYPE_2D || SRVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY) ) + LOG_ERROR_AND_THROW("Unsupported texture type. Only TEXTURE_TYPE_2D or TEXTURE_TYPE_2D_ARRAY is allowed"); + + if( SRVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + SRVDesc.Format = m_Desc.Format; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; + memset(&D3D11_SRVDesc, 0, sizeof(D3D11_SRVDesc)); + D3D11_SRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); + + + if( SRVDesc.TextureType == TEXTURE_TYPE_2D ) + { + if( m_Desc.SampleCount > 1 ) + { + D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + D3D11_SRVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + D3D11_SRVDesc.Texture2D.MipLevels = SRVDesc.NumMipLevels; + D3D11_SRVDesc.Texture2D.MostDetailedMip = SRVDesc.MostDetailedMip; + } + } + else if( SRVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) + { + if( m_Desc.SampleCount > 1 ) + { + D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + D3D11_SRVDesc.Texture2DMSArray.ArraySize = SRVDesc.NumArraySlices; + D3D11_SRVDesc.Texture2DMSArray.FirstArraySlice = SRVDesc.FirstArraySlice; + } + else + { + D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + D3D11_SRVDesc.Texture2DArray.ArraySize = SRVDesc.NumArraySlices; + D3D11_SRVDesc.Texture2DArray.FirstArraySlice = SRVDesc.FirstArraySlice; + D3D11_SRVDesc.Texture2DArray.MipLevels = SRVDesc.NumMipLevels; + D3D11_SRVDesc.Texture2DArray.MostDetailedMip = SRVDesc.MostDetailedMip; + } + } + else + { + UNEXPECTED( "Unexpected view type" ); + } + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Texture, &D3D11_SRVDesc, ppD3D11SRV ), + "Failed to create D3D11 shader resource view"); +} + +void Texture2D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ) +{ + VERIFY( ppD3D11RTV && *ppD3D11RTV == nullptr, "RTV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( RTVDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); + if( !(RTVDesc.TextureType == TEXTURE_TYPE_2D || RTVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY) ) + LOG_ERROR_AND_THROW( "Unsupported texture type. Only TEXTURE_TYPE_2D or TEXTURE_TYPE_2D_ARRAY is allowed" ); + + if( RTVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + RTVDesc.Format = m_Desc.Format; + } + + D3D11_RENDER_TARGET_VIEW_DESC D3D11_RTVDesc; + memset(&D3D11_RTVDesc, 0, sizeof(D3D11_RTVDesc)); + D3D11_RTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); + + if( RTVDesc.TextureType == TEXTURE_TYPE_2D ) + { + if( m_Desc.SampleCount > 1 ) + { + D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + D3D11_RTVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + D3D11_RTVDesc.Texture2D.MipSlice = RTVDesc.MostDetailedMip; + } + } + else if( RTVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) + { + if( m_Desc.SampleCount > 1 ) + { + D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + D3D11_RTVDesc.Texture2DMSArray.ArraySize = RTVDesc.NumArraySlices; + D3D11_RTVDesc.Texture2DMSArray.FirstArraySlice = RTVDesc.FirstArraySlice; + } + else + { + D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + D3D11_RTVDesc.Texture2DArray.ArraySize = RTVDesc.NumArraySlices; + D3D11_RTVDesc.Texture2DArray.FirstArraySlice = RTVDesc.FirstArraySlice; + D3D11_RTVDesc.Texture2DArray.MipSlice = RTVDesc.MostDetailedMip; + } + } + else + { + UNEXPECTED( "Unexpected view type" ); + } + + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRenderTargetView( m_pd3d11Texture, &D3D11_RTVDesc, ppD3D11RTV ), + "Failed to create D3D11 render target view"); +} + +void Texture2D_D3D11::CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ) +{ + VERIFY( ppD3D11DSV && *ppD3D11DSV == nullptr, "DSV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( DSVDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); + if( !(DSVDesc.TextureType == TEXTURE_TYPE_2D || DSVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY) ) + LOG_ERROR_AND_THROW("Unsupported texture type. Only TEXTURE_TYPE_2D or TEXTURE_TYPE_2D_ARRAY is allowed"); + + if( DSVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + DSVDesc.Format = m_Desc.Format; + } + + D3D11_DEPTH_STENCIL_VIEW_DESC D3D11_DSVDesc; + memset(&D3D11_DSVDesc, 0, sizeof(D3D11_DSVDesc)); + D3D11_DSVDesc.Format = TexFormatToDXGI_Format(DSVDesc.Format, BIND_DEPTH_STENCIL); + + if( DSVDesc.TextureType == TEXTURE_TYPE_2D ) + { + if( m_Desc.SampleCount > 1 ) + { + D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + D3D11_DSVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + D3D11_DSVDesc.Texture2D.MipSlice = DSVDesc.MostDetailedMip; + } + } + else if( DSVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) + { + if( m_Desc.SampleCount > 1 ) + { + D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; + D3D11_DSVDesc.Texture2DMSArray.ArraySize = DSVDesc.NumArraySlices; + D3D11_DSVDesc.Texture2DMSArray.FirstArraySlice = DSVDesc.FirstArraySlice; + } + else + { + D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + D3D11_DSVDesc.Texture2DArray.ArraySize = DSVDesc.NumArraySlices; + D3D11_DSVDesc.Texture2DArray.FirstArraySlice = DSVDesc.FirstArraySlice; + D3D11_DSVDesc.Texture2DArray.MipSlice = DSVDesc.MostDetailedMip; + } + } + else + { + UNEXPECTED( "Unexpected view type" ); + } + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateDepthStencilView( m_pd3d11Texture, &D3D11_DSVDesc, ppD3D11DSV ), + "Failed to create D3D11 depth stencil view"); +} + +void Texture2D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ) +{ + VERIFY( ppD3D11UAV && *ppD3D11UAV == nullptr, "UAV pointer address is null or contains non-null pointer to an existing object" ); + + if( m_Desc.SampleCount > 1 ) + LOG_ERROR_AND_THROW("UAVs are not allowed for multisampled resources"); + + VERIFY( UAVDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); + if( !(UAVDesc.TextureType == TEXTURE_TYPE_2D || UAVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY) ) + LOG_ERROR_AND_THROW( "Unsupported texture type. Only TEXTURE_TYPE_2D or TEXTURE_TYPE_2D_ARRAY is allowed" ); + + if( UAVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + UAVDesc.Format = m_Desc.Format; + } + + D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; + memset(&D3D11_UAVDesc, 0, sizeof(D3D11_UAVDesc)); + D3D11_UAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); + + if( UAVDesc.TextureType == TEXTURE_TYPE_2D ) + { + D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; + D3D11_UAVDesc.Texture2D.MipSlice = UAVDesc.MostDetailedMip; + } + else if( UAVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) + { + D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; + D3D11_UAVDesc.Texture2DArray.ArraySize = UAVDesc.NumArraySlices; + D3D11_UAVDesc.Texture2DArray.FirstArraySlice = UAVDesc.FirstArraySlice; + D3D11_UAVDesc.Texture2DArray.MipSlice = UAVDesc.MostDetailedMip; + } + else + { + UNEXPECTED( "Unexpected view type" ); + } + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Texture, &D3D11_UAVDesc, ppD3D11UAV ), + "Failed to create D3D11 unordered access view"); +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/Texture3D_D3D11.cpp b/Graphics/GraphicsEngineD3D11/src/Texture3D_D3D11.cpp new file mode 100644 index 00000000..9546660e --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/Texture3D_D3D11.cpp @@ -0,0 +1,154 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "Texture3D_D3D11.h" +#include "RenderDeviceD3D11Impl.h" +#include "D3D11TypeConversions.h" + +namespace Diligent +{ + +Texture3D_D3D11 :: Texture3D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : + TextureBaseD3D11(pRenderDeviceD3D11, TexDesc, InitData) +{ + auto D3D11TexFormat = TexFormatToDXGI_Format(m_Desc.Format, m_Desc.BindFlags); + auto D3D11BindFlags = BindFlagsToD3D11BindFlags(m_Desc.BindFlags); + auto D3D11CPUAccessFlags = CPUAccessFlagsToD3D11CPUAccessFlags(m_Desc.CPUAccessFlags); + auto D3D11Usage = UsageToD3D11Usage(m_Desc.Usage); + UINT MiscFlags = MiscTextureFlagsToD3D11Flags(m_Desc.MiscFlags); + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + + D3D11_TEXTURE3D_DESC Tex3DDesc = + { + m_Desc.Width, + m_Desc.Height, + m_Desc.Depth, + m_Desc.MipLevels, + D3D11TexFormat, + D3D11Usage, + D3D11BindFlags, + D3D11CPUAccessFlags, + MiscFlags + }; + + std::vector<D3D11_SUBRESOURCE_DATA> D3D11InitData; + PrepareD3D11InitData(InitData, Tex3DDesc.MipLevels, D3D11InitData); + + ID3D11Texture3D *ptex3D = nullptr; + HRESULT hr = pDeviceD3D11->CreateTexture3D(&Tex3DDesc, D3D11InitData.size() ? D3D11InitData.data() : nullptr, &ptex3D); + m_pd3d11Texture.Attach(ptex3D); + CHECK_D3D_RESULT_THROW( hr, "Failed to create the Direct3D11 Texture3D" ); +} + +void Texture3D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ) +{ + VERIFY( ppD3D11SRV && *ppD3D11SRV == nullptr, "SRV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( SRVDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); + if( SRVDesc.TextureType != TEXTURE_TYPE_3D ) + LOG_ERROR_AND_THROW("Unsupported texture view type. Only TEXTURE_TYPE_3D is allowed"); + + if( SRVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + SRVDesc.Format = m_Desc.Format; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; + memset(&D3D11_SRVDesc, 0, sizeof(D3D11_SRVDesc)); + D3D11_SRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); + + D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + D3D11_SRVDesc.Texture3D.MipLevels = SRVDesc.NumMipLevels; + D3D11_SRVDesc.Texture3D.MostDetailedMip = SRVDesc.MostDetailedMip; + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Texture, &D3D11_SRVDesc, ppD3D11SRV ), + "Failed to create D3D11 shader resource view"); +} + +void Texture3D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ) +{ + VERIFY( ppD3D11RTV && *ppD3D11RTV == nullptr, "RTV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( RTVDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); + if( RTVDesc.TextureType != TEXTURE_TYPE_3D ) + LOG_ERROR_AND_THROW( "Unsupported texture view type. Only TEXTURE_TYPE_3D is allowed" ); + + if( RTVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + RTVDesc.Format = m_Desc.Format; + } + + D3D11_RENDER_TARGET_VIEW_DESC D3D11_RTVDesc; + memset(&D3D11_RTVDesc, 0, sizeof(D3D11_RTVDesc)); + D3D11_RTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); + + D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + D3D11_RTVDesc.Texture3D.FirstWSlice = RTVDesc.FirstDepthSlice; + D3D11_RTVDesc.Texture3D.WSize = RTVDesc.NumDepthSlices; + D3D11_RTVDesc.Texture3D.MipSlice = RTVDesc.MostDetailedMip; + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRenderTargetView( m_pd3d11Texture, &D3D11_RTVDesc, ppD3D11RTV ), + "Failed to create D3D11 render target view"); +} + +void Texture3D_D3D11::CreateDSV( TextureViewDesc &pDSVDesc, ID3D11DepthStencilView **ppD3D11DSV ) +{ + LOG_ERROR_AND_THROW("Depth stencil views are not supported for 3D textures"); +} + +void Texture3D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ) +{ + VERIFY( ppD3D11UAV && *ppD3D11UAV == nullptr, "UAV pointer address is null or contains non-null pointer to an existing object" ); + + VERIFY( UAVDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); + if( UAVDesc.TextureType != TEXTURE_TYPE_3D ) + LOG_ERROR_AND_THROW("Unsupported texture view type. Only TEXTURE_TYPE_3D is allowed"); + + if( UAVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + UAVDesc.Format = m_Desc.Format; + } + + D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; + memset(&D3D11_UAVDesc, 0, sizeof(D3D11_UAVDesc)); + D3D11_UAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); + + D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; + D3D11_UAVDesc.Texture3D.FirstWSlice = UAVDesc.FirstDepthSlice; + D3D11_UAVDesc.Texture3D.WSize = UAVDesc.NumDepthSlices; + D3D11_UAVDesc.Texture3D.MipSlice = UAVDesc.MostDetailedMip; + + auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Texture, &D3D11_UAVDesc, ppD3D11UAV ), + "Failed to create D3D11 unordered access view"); +} + + +Texture3D_D3D11 :: ~Texture3D_D3D11() +{ +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp new file mode 100644 index 00000000..2462bec7 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp @@ -0,0 +1,216 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "TextureBaseD3D11.h" +#include "RenderDeviceD3D11Impl.h" +#include "DeviceContextD3D11Impl.h" +#include "D3D11TypeConversions.h" +#include "TextureViewD3D11Impl.h" + +using namespace Diligent; + +namespace Diligent +{ + +TextureBaseD3D11 :: TextureBaseD3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : + TTextureBase(pRenderDeviceD3D11, TexDesc) +{ + if( TexDesc.Usage == USAGE_STATIC && InitData.pSubResources == nullptr ) + LOG_ERROR_AND_THROW("Static Texture must be initialized with data at creation time"); +} + +IMPLEMENT_QUERY_INTERFACE( TextureBaseD3D11, IID_TextureD3D11, TTextureBase ) + +void TextureBaseD3D11::CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView ) +{ + VERIFY( ppView != nullptr, "View pointer address is null" ); + if( !ppView )return; + VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + + *ppView = nullptr; + + try + { + auto UpdatedViewDesc = ViewDesc; + + CorrectTextureViewDesc( UpdatedViewDesc ); + + RefCntAutoPtr<ID3D11View> pD3D11View; + switch( ViewDesc.ViewType ) + { + case TEXTURE_VIEW_SHADER_RESOURCE: + { + VERIFY( m_Desc.BindFlags & BIND_SHADER_RESOURCE, "BIND_SHADER_RESOURCE flag is not set" ); + ID3D11ShaderResourceView *pSRV = nullptr; + CreateSRV( UpdatedViewDesc, &pSRV ); + pD3D11View.Attach( pSRV ); + } + break; + + case TEXTURE_VIEW_RENDER_TARGET: + { + VERIFY( m_Desc.BindFlags & BIND_RENDER_TARGET, "BIND_RENDER_TARGET flag is not set" ); + ID3D11RenderTargetView *pRTV = nullptr; + CreateRTV( UpdatedViewDesc, &pRTV ); + pD3D11View.Attach( pRTV ); + } + break; + + case TEXTURE_VIEW_DEPTH_STENCIL: + { + VERIFY( m_Desc.BindFlags & BIND_DEPTH_STENCIL, "BIND_DEPTH_STENCIL is not set" ); + ID3D11DepthStencilView *pDSV = nullptr; + CreateDSV( UpdatedViewDesc, &pDSV ); + pD3D11View.Attach( pDSV ); + } + break; + + case TEXTURE_VIEW_UNORDERED_ACCESS: + { + VERIFY( m_Desc.BindFlags & BIND_UNORDERED_ACCESS, "BIND_UNORDERED_ACCESS flag is not set" ); + ID3D11UnorderedAccessView *pUAV = nullptr; + CreateUAV( UpdatedViewDesc, &pUAV ); + pD3D11View.Attach( pUAV ); + } + break; + + default: UNEXPECTED( "Unknown view type" ); break; + } + + auto pViewD3D11 = new TextureViewD3D11Impl( GetDevice(), UpdatedViewDesc, this, pD3D11View, bIsDefaultView ); + VERIFY( pViewD3D11->GetDesc().ViewType == ViewDesc.ViewType, "Incorrect view type" ); + + if( bIsDefaultView ) + *ppView = pViewD3D11; + else + pViewD3D11->QueryInterface(IID_TextureView, reinterpret_cast<IObject**>(ppView) ); + } + catch( const std::runtime_error & ) + { + const auto *ViewTypeName = GetTexViewTypeLiteralName(ViewDesc.ViewType); + LOG_ERROR("Failed to create view \"", ViewDesc.Name ? ViewDesc.Name : "", "\" (", ViewTypeName, ") for texture \"", m_Desc.Name ? m_Desc.Name : "", "\"" ) + } +} + +void TextureBaseD3D11 :: PrepareD3D11InitData(const TextureData &InitData, Uint32 NumSubresources, std::vector<D3D11_SUBRESOURCE_DATA> &D3D11InitData) +{ + if( InitData.pSubResources ) + { + if( NumSubresources == InitData.NumSubresources ) + { + D3D11InitData.resize(NumSubresources); + for(UINT Subres=0; Subres < NumSubresources; ++Subres) + { + auto &CurrSubres = InitData.pSubResources[Subres]; + D3D11InitData[Subres].pSysMem = CurrSubres.pData; + D3D11InitData[Subres].SysMemPitch = CurrSubres.Stride; + D3D11InitData[Subres].SysMemSlicePitch = CurrSubres.DepthStride; + } + } + else + UNEXPECTED( "Incorrect number of subrsources" ); + } +} + + +TextureBaseD3D11 :: ~TextureBaseD3D11() +{ +} + +void TextureBaseD3D11::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + TTextureBase::UpdateData( pContext, MipLevel, Slice, DstBox, SubresData ); + VERIFY( m_Desc.Usage == USAGE_DEFAULT, "Only default usage resiurces can be updated with UpdateData()" ); + + auto *pd3d11DeviceContext = static_cast<DeviceContextD3D11Impl*>(pContext)->GetD3D11DeviceContext(); + + D3D11_BOX D3D11Box; + D3D11Box.left = DstBox.MinX; + D3D11Box.right = DstBox.MaxX; + D3D11Box.top = DstBox.MinY; + D3D11Box.bottom = DstBox.MaxY; + D3D11Box.front = DstBox.MinZ; + D3D11Box.back = DstBox.MaxZ; + auto SubresIndex = D3D11CalcSubresource(MipLevel, Slice, m_Desc.MipLevels); + pd3d11DeviceContext->UpdateSubresource(m_pd3d11Texture, SubresIndex, &D3D11Box, SubresData.pData, SubresData.Stride, SubresData.DepthStride); +} + +void TextureBaseD3D11 :: CopyData(IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ) +{ + TTextureBase::CopyData( pContext, pSrcTexture, SrcMipLevel, SrcSlice, pSrcBox, + DstMipLevel, DstSlice, DstX, DstY, DstZ ); + + auto *pd3d11DeviceContext = ValidatedCast<DeviceContextD3D11Impl>(pContext )->GetD3D11DeviceContext(); + auto *pSrTextureBaseD3D11 = ValidatedCast<TextureBaseD3D11>( pSrcTexture ); + + D3D11_BOX D3D11SrcBox, *pD3D11SrcBox = nullptr; + if( pSrcBox ) + { + D3D11SrcBox.left = pSrcBox->MinX; + D3D11SrcBox.right = pSrcBox->MaxX; + D3D11SrcBox.top = pSrcBox->MinY; + D3D11SrcBox.bottom = pSrcBox->MaxY; + D3D11SrcBox.front = pSrcBox->MinZ; + D3D11SrcBox.back = pSrcBox->MaxZ; + pD3D11SrcBox = &D3D11SrcBox; + } + auto SrcSubRes = D3D11CalcSubresource(SrcMipLevel, SrcSlice, pSrTextureBaseD3D11->GetDesc().MipLevels); + auto DstSubRes = D3D11CalcSubresource(DstMipLevel, DstSlice, m_Desc.MipLevels); + pd3d11DeviceContext->CopySubresourceRegion(m_pd3d11Texture, DstSubRes, DstX, DstY, DstZ, pSrTextureBaseD3D11->GetD3D11Texture(), SrcSubRes, pD3D11SrcBox); +} + +void TextureBaseD3D11 :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) +{ + TTextureBase::Map( pContext, MapType, MapFlags, pMappedData ); + + //auto *pd3d11DeviceContext = static_cast<RenderDeviceD3D11Impl*>( static_cast<CRenderDevice*>(m_pDevice) )->GetD3D11DeviceContext(); + //auto d3d11MapType = MapTypeToD3D11MapType(MapType); + //auto d3d11MapFlags = MapFlagsToD3D11MapFlags(MapFlags); + + //D3D11_MAPPED_SUBRESOURCE MappedBuff; + //pd3d11DeviceContext->Map(m_pd3d11Texture, 0, d3d11MapType, d3d11MapFlags, &MappedBuff); + + //pMappedData = MappedBuff.pData; + + //VERIFY( pMappedData, "Map failed" ); +} + +void TextureBaseD3D11::Unmap( IDeviceContext *pContext ) +{ + TTextureBase::Unmap( pContext ); + + //auto *pd3d11DeviceContext = static_cast<RenderDeviceD3D11Impl*>( static_cast<CRenderDevice*>(m_pDevice) )->GetD3D11DeviceContext(); + //pd3d11DeviceContext->Unmap(m_pd3d11Texture, 0); +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/TextureViewD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/TextureViewD3D11Impl.cpp new file mode 100644 index 00000000..1cebd403 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/TextureViewD3D11Impl.cpp @@ -0,0 +1,61 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "TextureViewD3D11Impl.h" +#include "DeviceContextD3D11Impl.h" + +namespace Diligent +{ + +TextureViewD3D11Impl::TextureViewD3D11Impl( IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + ITexture *pTexture, + ID3D11View* pD3D11View, + bool bIsDefaultView ) : + TTextureViewBase( pDevice, ViewDesc, pTexture, bIsDefaultView ), + m_pD3D11View( pD3D11View ) +{ +} + +ID3D11View* TextureViewD3D11Impl::GetD3D11View() +{ + return m_pD3D11View; +} + +IMPLEMENT_QUERY_INTERFACE( TextureViewD3D11Impl, IID_TextureViewD3D11, TTextureViewBase ) + +void TextureViewD3D11Impl::GenerateMips( IDeviceContext *pContext ) +{ + VERIFY( m_Desc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "GenerateMips() is allowed for shader resource views only, ", GetTexViewTypeLiteralName(m_Desc.ViewType), " is not allowed." ); + if( m_Desc.ViewType != TEXTURE_VIEW_SHADER_RESOURCE ) + { + LOG_ERROR("GenerateMips() is allowed for shader resource views only, ", GetTexViewTypeLiteralName(m_Desc.ViewType), " is not allowed."); + return; + } + auto *pd3d11Ctx = ValidatedCast<IDeviceContextD3D11>( pContext )->GetD3D11DeviceContext(); + auto *pd3d11SRV = static_cast<ID3D11ShaderResourceView*>( GetD3D11View() ); + pd3d11Ctx->GenerateMips(pd3d11SRV); +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/VertexDescD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/VertexDescD3D11Impl.cpp new file mode 100644 index 00000000..46be4675 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/VertexDescD3D11Impl.cpp @@ -0,0 +1,72 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "VertexDescD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" +#include "ShaderD3D11Impl.h" +#include "D3D11TypeConversions.h" + +namespace Diligent +{ + +VertexDescD3D11Impl::VertexDescD3D11Impl(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const LayoutDesc &LayoutDesc, IShader *pVertexShader) : + TVertexDescriptionBase( pRenderDeviceD3D11, LayoutDesc ) +{ + // Use m_LayoutDesc as original LayoutDescription might have been corrected + auto *pLayoutElements = m_LayoutElements.data(); + auto NumElements = m_LayoutElements.size(); + + if( pVertexShader->GetDesc().ShaderType != SHADER_TYPE_VERTEX ) + LOG_ERROR_AND_THROW( "Invalid shader type provided for the input layout creation" ); + std::vector<D3D11_INPUT_ELEMENT_DESC> InputElements; + ID3DBlob *pVSByteCode = static_cast<ShaderD3D11Impl*>(pVertexShader)->m_pShaderByteCode; + if( !pVSByteCode ) + LOG_ERROR_AND_THROW( "Vertex Shader byte code does not exist" ); + + InputElements.resize(NumElements); + for(Uint32 iElem=0; iElem < NumElements; ++iElem) + { + const auto &CurrElem = pLayoutElements[iElem]; + auto &D3D11Elem = InputElements[iElem]; + D3D11Elem.SemanticName = "ATTRIB"; + D3D11Elem.SemanticIndex = CurrElem.InputIndex; + D3D11Elem.AlignedByteOffset = CurrElem.RelativeOffset; + D3D11Elem.InputSlot = CurrElem.BufferSlot; + D3D11Elem.Format = TypeToDXGI_Format(CurrElem.ValueType, CurrElem.NumComponents, CurrElem.IsNormalized); + D3D11Elem.InputSlotClass = (CurrElem.Frequency == LayoutElement::FREQUENCY_PER_VERTEX) ? D3D11_INPUT_PER_VERTEX_DATA : D3D11_INPUT_PER_INSTANCE_DATA; + D3D11Elem.InstanceDataStepRate = (CurrElem.Frequency == LayoutElement::FREQUENCY_PER_VERTEX) ? 0 : CurrElem.InstanceDataStepRate; + } + + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateInputLayout(InputElements.data(), static_cast<UINT>(InputElements.size()), pVSByteCode->GetBufferPointer(), pVSByteCode->GetBufferSize(), &m_pd3d11InputLayout), + "Failed to create the Direct3D11 input layout"); +} + +VertexDescD3D11Impl::~VertexDescD3D11Impl() +{ +} + +IMPLEMENT_QUERY_INTERFACE( VertexDescD3D11Impl, IID_VertexDescriptionD3D11, TVertexDescriptionBase ) + +} diff --git a/Graphics/GraphicsEngineD3D11/src/pch.cpp b/Graphics/GraphicsEngineD3D11/src/pch.cpp new file mode 100644 index 00000000..c7d1ec78 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/pch.cpp @@ -0,0 +1,31 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// stdafx.cpp : source file that includes just the standard includes +// GraphicsEngineD3D11.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "pch.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Debug.h b/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Debug.h new file mode 100644 index 00000000..b46f53e0 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Debug.h @@ -0,0 +1,199 @@ +/* + This file is only used by IntelliSense (VisualStudio code suggestion system) + DO NOT INCLUDE THIS FILE FROM YOUR ACTUAL SOURCE FILES. + This file lists the preprocessor macros extracted from your GCC. + It is needed for IntelliSense to parse other header files correctly. +*/ +#ifdef _MSC_VER +#define _GNU_SOURCE 1 +#define __ANDROID__ 1 +#define __APCS_32__ 1 +#define __ARMEL__ 1 +#define __ARM_ARCH 7 +#define __ARM_ARCH_7A__ 1 +#define __ARM_ARCH_PROFILE A +#define __ARM_EABI__ 1 +#define __ARM_PCS 1 +#define __ARM_VFPV3__ 1 +#define __ATOMIC_ACQUIRE 2 +#define __ATOMIC_ACQ_REL 4 +#define __ATOMIC_CONSUME 1 +#define __ATOMIC_RELAXED 0 +#define __ATOMIC_RELEASE 3 +#define __ATOMIC_SEQ_CST 5 +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __CHAR16_TYPE__ unsigned short +#define __CHAR32_TYPE__ unsigned int +#define __CHAR_BIT__ 8 +#define __CHAR_UNSIGNED__ 1 +#define __CONSTANT_CFSTRINGS__ 1 +#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 +#define __DBL_DIG__ 15 +#define __DBL_EPSILON__ 2.2204460492503131e-16 +#define __DBL_HAS_DENORM__ 1 +#define __DBL_HAS_INFINITY__ 1 +#define __DBL_HAS_QUIET_NAN__ 1 +#define __DBL_MANT_DIG__ 53 +#define __DBL_MAX_10_EXP__ 308 +#define __DBL_MAX_EXP__ 1024 +#define __DBL_MAX__ 1.7976931348623157e+308 +#define __DBL_MIN_10_EXP__ (-307) +#define __DBL_MIN_EXP__ (-1021) +#define __DBL_MIN__ 2.2250738585072014e-308 +#define __DECIMAL_DIG__ 17 +#define __DEPRECATED 1 +#define __ELF__ 1 +#define __EXCEPTIONS 1 +#define __FINITE_MATH_ONLY__ 0 +#define __FLT_DENORM_MIN__ 1.40129846e-45F +#define __FLT_DIG__ 6 +#define __FLT_EPSILON__ 1.19209290e-7F +#define __FLT_EVAL_METHOD__ 0 +#define __FLT_HAS_DENORM__ 1 +#define __FLT_HAS_INFINITY__ 1 +#define __FLT_HAS_QUIET_NAN__ 1 +#define __FLT_MANT_DIG__ 24 +#define __FLT_MAX_10_EXP__ 38 +#define __FLT_MAX_EXP__ 128 +#define __FLT_MAX__ 3.40282347e+38F +#define __FLT_MIN_10_EXP__ (-37) +#define __FLT_MIN_EXP__ (-125) +#define __FLT_MIN__ 1.17549435e-38F +#define __FLT_RADIX__ 2 +#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 +#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 +#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 +#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 +#define __GCC_ATOMIC_INT_LOCK_FREE 2 +#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 +#define __GCC_ATOMIC_LONG_LOCK_FREE 2 +#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 +#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 +#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 +#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 +#define __GNUC_GNU_INLINE__ 1 +#define __GNUC_MINOR__ 2 +#define __GNUC_PATCHLEVEL__ 1 +#define __GNUC__ 4 +#define __GNUG__ 4 +#define __GXX_ABI_VERSION 1002 +#define __GXX_EXPERIMENTAL_CXX0X__ 1 +#define __GXX_RTTI 1 +#define __GXX_WEAK__ 1 +#define __INT16_TYPE__ short +#define __INT32_TYPE__ int +#define __INT64_C_SUFFIX__ LL +#define __INT64_TYPE__ long long int +#define __INT8_TYPE__ char +#define __INTMAX_MAX__ 9223372036854775807LL +#define __INTMAX_TYPE__ long long int +#define __INTMAX_WIDTH__ 64 +#define __INTPTR_TYPE__ long int +#define __INTPTR_WIDTH__ 32 +#define __INT_MAX__ 2147483647 +#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L +#define __LDBL_DIG__ 15 +#define __LDBL_EPSILON__ 2.2204460492503131e-16L +#define __LDBL_HAS_DENORM__ 1 +#define __LDBL_HAS_INFINITY__ 1 +#define __LDBL_HAS_QUIET_NAN__ 1 +#define __LDBL_MANT_DIG__ 53 +#define __LDBL_MAX_10_EXP__ 308 +#define __LDBL_MAX_EXP__ 1024 +#define __LDBL_MAX__ 1.7976931348623157e+308L +#define __LDBL_MIN_10_EXP__ (-307) +#define __LDBL_MIN_EXP__ (-1021) +#define __LDBL_MIN__ 2.2250738585072014e-308L +#define __LITTLE_ENDIAN__ 1 +#define __LONG_LONG_MAX__ 9223372036854775807LL +#define __LONG_MAX__ 2147483647L +#define __NO_INLINE__ 1 +#define __ORDER_BIG_ENDIAN__ 4321 +#define __ORDER_LITTLE_ENDIAN__ 1234 +#define __ORDER_PDP_ENDIAN__ 3412 +#define __PIC__ 1 +#define __POINTER_WIDTH__ 32 +#define __PRAGMA_REDEFINE_EXTNAME 1 +#define __PTRDIFF_TYPE__ int +#define __PTRDIFF_WIDTH__ 32 +#define __REGISTER_PREFIX__ +#define __SCHAR_MAX__ 127 +#define __SHRT_MAX__ 32767 +#define __SIG_ATOMIC_WIDTH__ 32 +#define __SIZEOF_DOUBLE__ 8 +#define __SIZEOF_FLOAT__ 4 +#define __SIZEOF_INT__ 4 +#define __SIZEOF_LONG_DOUBLE__ 8 +#define __SIZEOF_LONG_LONG__ 8 +#define __SIZEOF_LONG__ 4 +#define __SIZEOF_POINTER__ 4 +#define __SIZEOF_PTRDIFF_T__ 4 +#define __SIZEOF_SHORT__ 2 +#define __SIZEOF_SIZE_T__ 4 +#define __SIZEOF_WCHAR_T__ 4 +#define __SIZEOF_WINT_T__ 4 +#define __SIZE_MAX__ 4294967295U +#define __SIZE_TYPE__ unsigned int +#define __SIZE_WIDTH__ 32 +#define __SSP__ 1 +#define __STDC_HOSTED__ 1 +#define __STDC_UTF_16__ 1 +#define __STDC_UTF_32__ 1 +#define __STDC__ 1 +#define __STRICT_ANSI__ 1 +#define __THUMB_INTERWORK__ 1 +#define __UINTMAX_TYPE__ long long unsigned int +#define __USER_LABEL_PREFIX__ +#define __VERSION__ "4.2.1 Compatible Clang 3.4 (https://bitbucket.org/loganchien/clang c34bb12af3af42f671296cdb978b34b931062d2a) (https://bitbucket.org/loganchien/llvm d09f2eff406d17c86d51db7660bd374cf092e6ed)" +#define __VFP_FP__ 1 +#define __WCHAR_MAX__ 4294967295U +#define __WCHAR_TYPE__ unsigned int +#define __WCHAR_UNSIGNED__ 1 +#define __WCHAR_WIDTH__ 32 +#define __WINT_TYPE__ unsigned int +#define __WINT_UNSIGNED__ 1 +#define __WINT_WIDTH__ 32 +#define __arm 1 +#define __arm__ 1 +#define __clang__ 1 +#define __clang_major__ 3 +#define __clang_minor__ 4 +#define __clang_patchlevel__ 0 +#define __clang_version__ "3.4 (https://bitbucket.org/loganchien/clang c34bb12af3af42f671296cdb978b34b931062d2a) (https://bitbucket.org/loganchien/llvm d09f2eff406d17c86d51db7660bd374cf092e6ed)" +#define __cplusplus 201103L +#define __cpp_attributes 200809 +#define __cpp_constexpr 200704 +#define __cpp_decltype 200707 +#define __cpp_lambdas 200907 +#define __cpp_raw_strings 200710 +#define __cpp_rvalue_references 200610 +#define __cpp_static_assert 200410 +#define __cpp_unicode_characters 200704 +#define __cpp_unicode_literals 200710 +#define __cpp_user_defined_literals 200809 +#define __cpp_variadic_templates 200704 +#define __gnu_linux__ 1 +#define __linux 1 +#define __linux__ 1 +#define __llvm__ 1 +#define __pic__ 1 +#define __private_extern__ extern +#define __unix 1 +#define __unix__ 1 +#define ANDROID +#endif + +// --- Include directories begin --- // +//C:/Android/ndk/platforms/android-3/arch-arm/usr/include +//C:/Users/eayusov/Documents/Sandbox/Common/Android/jni/../../include +//C:\Android\ndk\toolchains\llvm-3.4\prebuilt\windows\bin\..\lib\clang\3.4\include +// --- Library directories end --- // + + +// --- Library directories begin --- // +// --- Library directories begin --- // + diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Release.h b/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Release.h new file mode 100644 index 00000000..6ca2abab --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Release.h @@ -0,0 +1,380 @@ +/* + This file is only used by IntelliSense (VisualStudio code suggestion system) + DO NOT INCLUDE THIS FILE FROM YOUR ACTUAL SOURCE FILES. + This file lists the preprocessor macros extracted from your GCC. + It is needed for IntelliSense to parse other header files correctly. +*/ +#ifdef _MSC_VER +#define __DBL_MIN_EXP__ (-1021) +#define __HQ_FBIT__ 15 +#define __UINT_LEAST16_MAX__ 65535 +#define __ARM_SIZEOF_WCHAR_T 32 +#define __ATOMIC_ACQUIRE 2 +#define __SFRACT_IBIT__ 0 +#define __FLT_MIN__ 1.1754943508222875e-38F +#define __UFRACT_MAX__ 0XFFFFP-16UR +#define __UINT_LEAST8_TYPE__ unsigned char +#define __DQ_FBIT__ 63 +#define __ARM_FEATURE_SAT 1 +#define __ULFRACT_FBIT__ 32 +#define __SACCUM_EPSILON__ 0x1P-7HK +#define __CHAR_BIT__ 8 +#define __USQ_IBIT__ 0 +#define __UINT8_MAX__ 255 +#define __ACCUM_FBIT__ 15 +#define __ANDROID__ 1 +#define __WINT_MAX__ 4294967295U +#define __USFRACT_FBIT__ 8 +#define __ORDER_LITTLE_ENDIAN__ 1234 +#define __SIZE_MAX__ 4294967295U +#define __ARM_ARCH_ISA_ARM 1 +#define __WCHAR_MAX__ 4294967295U +#define __LACCUM_IBIT__ 32 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +#define __DBL_DENORM_MIN__ double(4.9406564584124654e-324L) +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 +#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 +#define __FLT_EVAL_METHOD__ 0 +#define __unix__ 1 +#define __LLACCUM_MAX__ 0X7FFFFFFFFFFFFFFFP-31LLK +#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 +#define __FRACT_FBIT__ 15 +#define __UINT_FAST64_MAX__ 18446744073709551615ULL +#define __SIG_ATOMIC_TYPE__ int +#define __UACCUM_FBIT__ 16 +#define __DBL_MIN_10_EXP__ (-307) +#define __FINITE_MATH_ONLY__ 0 +#define __ARMEL__ 1 +#define __ARM_FEATURE_UNALIGNED 1 +#define __LFRACT_IBIT__ 0 +#define __GNUC_PATCHLEVEL__ 0 +#define __LFRACT_MAX__ 0X7FFFFFFFP-31LR +#define __UINT_FAST8_MAX__ 255 +#define __DEC64_MAX_EXP__ 385 +#define __UINT_LEAST64_MAX__ 18446744073709551615ULL +#define __SA_FBIT__ 15 +#define __SHRT_MAX__ 32767 +#define __LDBL_MAX__ 1.7976931348623157e+308L +#define __FRACT_MAX__ 0X7FFFP-15R +#define __UFRACT_FBIT__ 16 +#define __ARM_FP 12 +#define __UFRACT_MIN__ 0.0UR +#define __UINT_LEAST8_MAX__ 255 +#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 +#define __UINTMAX_TYPE__ long long unsigned int +#define __LLFRACT_EPSILON__ 0x1P-63LLR +#define __linux 1 +#define __DEC32_EPSILON__ 1E-6DF +#define __CHAR_UNSIGNED__ 1 +#define __UINT32_MAX__ 4294967295U +#define __GXX_EXPERIMENTAL_CXX0X__ 1 +#define __ULFRACT_MAX__ 0XFFFFFFFFP-32ULR +#define __TA_IBIT__ 64 +#define __LDBL_MAX_EXP__ 1024 +#define __WINT_MIN__ 0U +#define __linux__ 1 +#define __ULLFRACT_MIN__ 0.0ULLR +#define __SCHAR_MAX__ 127 +#define __WCHAR_MIN__ 0U +#define __DBL_DIG__ 15 +#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 +#define __LLACCUM_MIN__ (-0X1P31LLK-0X1P31LLK) +#define __SIZEOF_INT__ 4 +#define __SIZEOF_POINTER__ 4 +#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 +#define __USACCUM_IBIT__ 8 +#define __USER_LABEL_PREFIX__ +#define __STDC_HOSTED__ 1 +#define __LDBL_HAS_INFINITY__ 1 +#define __LFRACT_MIN__ (-0.5LR-0.5LR) +#define __HA_IBIT__ 8 +#define __ARM_NEON_FP 4 +#define __TQ_IBIT__ 0 +#define __FLT_EPSILON__ 1.1920928955078125e-7F +#define __APCS_32__ 1 +#define __GXX_WEAK__ 1 +#define __USFRACT_IBIT__ 0 +#define __LDBL_MIN__ 2.2250738585072014e-308L +#define __FRACT_MIN__ (-0.5R-0.5R) +#define __DEC32_MAX__ 9.999999E96DF +#define __DA_IBIT__ 32 +#define __ARM_SIZEOF_MINIMAL_ENUM 4 +#define __INT32_MAX__ 2147483647 +#define __UQQ_FBIT__ 8 +#define __SIZEOF_LONG__ 4 +#define __UACCUM_MAX__ 0XFFFFFFFFP-16UK +#define __DECIMAL_DIG__ 17 +#define __LFRACT_EPSILON__ 0x1P-31LR +#define __ULFRACT_MIN__ 0.0ULR +#define __LDBL_HAS_QUIET_NAN__ 1 +#define __ULACCUM_IBIT__ 32 +#define __UACCUM_EPSILON__ 0x1P-16UK +#define __GNUC__ 4 +#define __ULLACCUM_MAX__ 0XFFFFFFFFFFFFFFFFP-32ULLK +#define __GXX_RTTI 1 +#define __HQ_IBIT__ 0 +#define __FLT_HAS_DENORM__ 1 +#define __SIZEOF_LONG_DOUBLE__ 8 +#define __BIGGEST_ALIGNMENT__ 8 +#define __GNUC_STDC_INLINE__ 1 +#define __DQ_IBIT__ 0 +#define __DBL_MAX__ double(1.7976931348623157e+308L) +#define __ULFRACT_IBIT__ 0 +#define __INT_FAST32_MAX__ 2147483647 +#define __DBL_HAS_INFINITY__ 1 +#define __INT64_MAX__ 9223372036854775807LL +#define __ACCUM_IBIT__ 16 +#define __DEC32_MIN_EXP__ (-94) +#define __THUMB_INTERWORK__ 1 +#define __LACCUM_MAX__ 0X7FFFFFFFFFFFFFFFP-31LK +#define __INT_FAST16_TYPE__ int +#define __STRICT_ANSI__ 1 +#define __LDBL_HAS_DENORM__ 1 +#define __ARM_FEATURE_LDREX 15 +#define __cplusplus 201103L +#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL +#define __INT_LEAST32_MAX__ 2147483647 +#define __ARM_PCS 1 +#define __DEC32_MIN__ 1E-95DF +#define __ACCUM_MAX__ 0X7FFFFFFFP-15K +#define __DEPRECATED 1 +#define __DBL_MAX_EXP__ 1024 +#define __USACCUM_EPSILON__ 0x1P-8UHK +#define __DEC128_EPSILON__ 1E-33DL +#define __SFRACT_MAX__ 0X7FP-7HR +#define __FRACT_IBIT__ 0 +#define __PTRDIFF_MAX__ 2147483647 +#define __UACCUM_MIN__ 0.0UK +#define __UACCUM_IBIT__ 16 +#define __GNUG__ 4 +#define __LONG_LONG_MAX__ 9223372036854775807LL +#define __SIZEOF_SIZE_T__ 4 +#define __ULACCUM_MAX__ 0XFFFFFFFFFFFFFFFFP-32ULK +#define __SIZEOF_WINT_T__ 4 +#define __SA_IBIT__ 16 +#define __ULLACCUM_MIN__ 0.0ULLK +#define __GXX_ABI_VERSION 1002 +#define __UTA_FBIT__ 64 +#define __FLT_MIN_EXP__ (-125) +#define __USFRACT_MAX__ 0XFFP-8UHR +#define __UFRACT_IBIT__ 0 +#define __ARM_FEATURE_QBIT 1 +#define __INT_FAST64_TYPE__ long long int +#define __DBL_MIN__ double(2.2250738585072014e-308L) +#define __FLT_MIN_10_EXP__ (-37) +#define __LACCUM_MIN__ (-0X1P31LK-0X1P31LK) +#define __ULLACCUM_FBIT__ 32 +#define __GXX_TYPEINFO_EQUALITY_INLINE 0 +#define __ULLFRACT_EPSILON__ 0x1P-64ULLR +#define __DEC128_MIN__ 1E-6143DL +#define __REGISTER_PREFIX__ +#define __UINT16_MAX__ 65535 +#define __DBL_HAS_DENORM__ 1 +#define __ACCUM_MIN__ (-0X1P15K-0X1P15K) +#define __SQ_IBIT__ 0 +#define __UINT8_TYPE__ unsigned char +#define __UHA_FBIT__ 8 +#define __NO_INLINE__ 1 +#define __SFRACT_MIN__ (-0.5HR-0.5HR) +#define __UTQ_FBIT__ 128 +#define __FLT_MANT_DIG__ 24 +#define __VERSION__ "4.8" +#define __ULLFRACT_FBIT__ 64 +#define __FRACT_EPSILON__ 0x1P-15R +#define __ULACCUM_MIN__ 0.0ULK +#define __UDA_FBIT__ 32 +#define __LLACCUM_EPSILON__ 0x1P-31LLK +#define __GCC_ATOMIC_INT_LOCK_FREE 2 +#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __USFRACT_MIN__ 0.0UHR +#define __ULLACCUM_IBIT__ 32 +#define __UQQ_IBIT__ 0 +#define __DEC64_EPSILON__ 1E-15DD +#define __ORDER_PDP_ENDIAN__ 3412 +#define __DEC128_MIN_EXP__ (-6142) +#define __UHQ_FBIT__ 16 +#define __LLACCUM_FBIT__ 31 +#define __INT_FAST32_TYPE__ int +#define __UINT_LEAST16_TYPE__ short unsigned int +#define __INT16_MAX__ 32767 +#define __SIZE_TYPE__ unsigned int +#define __UINT64_MAX__ 18446744073709551615ULL +#define __UDQ_FBIT__ 64 +#define __INT8_TYPE__ signed char +#define __ELF__ 1 +#define __ULFRACT_EPSILON__ 0x1P-32ULR +#define __LLFRACT_FBIT__ 63 +#define __FLT_RADIX__ 2 +#define __INT_LEAST16_TYPE__ short int +#define __ARM_ARCH_PROFILE 65 +#define __LDBL_EPSILON__ 2.2204460492503131e-16L +#define __SACCUM_MAX__ 0X7FFFP-7HK +#define __SIG_ATOMIC_MAX__ 2147483647 +#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +#define __VFP_FP__ 1 +#define __SIZEOF_PTRDIFF_T__ 4 +#define __LACCUM_EPSILON__ 0x1P-31LK +#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF +#define __INT_FAST16_MAX__ 2147483647 +#define __UINT_FAST32_MAX__ 4294967295U +#define __UINT_LEAST64_TYPE__ long long unsigned int +#define __USACCUM_MAX__ 0XFFFFP-8UHK +#define __SFRACT_EPSILON__ 0x1P-7HR +#define __FLT_HAS_QUIET_NAN__ 1 +#define __FLT_MAX_10_EXP__ 38 +#define __LONG_MAX__ 2147483647L +#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL +#define __FLT_HAS_INFINITY__ 1 +#define __unix 1 +#define __USA_FBIT__ 16 +#define __UINT_FAST16_TYPE__ unsigned int +#define __DEC64_MAX__ 9.999999999999999E384DD +#define __CHAR16_TYPE__ short unsigned int +#define __PRAGMA_REDEFINE_EXTNAME 1 +#define __INT_LEAST16_MAX__ 32767 +#define __DEC64_MANT_DIG__ 16 +#define __UINT_LEAST32_MAX__ 4294967295U +#define __SACCUM_FBIT__ 7 +#define __GCC_ATOMIC_LONG_LOCK_FREE 2 +#define __INT_LEAST64_TYPE__ long long int +#define __ARM_FEATURE_CLZ 1 +#define __INT16_TYPE__ short int +#define __INT_LEAST8_TYPE__ signed char +#define __SQ_FBIT__ 31 +#define __DEC32_MAX_EXP__ 97 +#define __ARM_ARCH_ISA_THUMB 2 +#define __INT_FAST8_MAX__ 127 +#define __ARM_ARCH 7 +#define __INTPTR_MAX__ 2147483647 +#define __QQ_FBIT__ 7 +#define __UTA_IBIT__ 64 +#define __EXCEPTIONS 1 +#define __LDBL_MANT_DIG__ 53 +#define __SFRACT_FBIT__ 7 +#define __SACCUM_MIN__ (-0X1P7HK-0X1P7HK) +#define __DBL_HAS_QUIET_NAN__ 1 +#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) +#define __INTPTR_TYPE__ int +#define __UINT16_TYPE__ short unsigned int +#define __WCHAR_TYPE__ unsigned int +#define __SIZEOF_FLOAT__ 4 +#define __USQ_FBIT__ 32 +#define __pic__ 1 +#define __UINTPTR_MAX__ 4294967295U +#define __DEC64_MIN_EXP__ (-382) +#define __INT_FAST64_MAX__ 9223372036854775807LL +#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 +#define __FLT_DIG__ 6 +#define __UINT_FAST64_TYPE__ long long unsigned int +#define __INT_MAX__ 2147483647 +#define __LACCUM_FBIT__ 31 +#define __USACCUM_MIN__ 0.0UHK +#define __UHA_IBIT__ 8 +#define __INT64_TYPE__ long long int +#define __FLT_MAX_EXP__ 128 +#define __UTQ_IBIT__ 0 +#define __DBL_MANT_DIG__ 53 +#define __INT_LEAST64_MAX__ 9223372036854775807LL +#define __DEC64_MIN__ 1E-383DD +#define __WINT_TYPE__ unsigned int +#define __UINT_LEAST32_TYPE__ unsigned int +#define __SIZEOF_SHORT__ 2 +#define __ULLFRACT_IBIT__ 0 +#define __LDBL_MIN_EXP__ (-1021) +#define __arm__ 1 +#define __UDA_IBIT__ 32 +#define __INT_LEAST8_MAX__ 127 +#define __SSP__ 1 +#define __LFRACT_FBIT__ 31 +#define __WCHAR_UNSIGNED__ 1 +#define __ARM_ARCH_7A__ 1 +#define __LDBL_MAX_10_EXP__ 308 +#define __ATOMIC_RELAXED 0 +#define __DBL_EPSILON__ double(2.2204460492503131e-16L) +#define __ARM_FEATURE_SIMD32 1 +#define __INT_LEAST32_TYPE__ int +#define __SIZEOF_WCHAR_T__ 4 +#define __UINT64_TYPE__ long long unsigned int +#define __LLFRACT_MAX__ 0X7FFFFFFFFFFFFFFFP-63LLR +#define __TQ_FBIT__ 127 +#define __INT_FAST8_TYPE__ signed char +#define __ULLACCUM_EPSILON__ 0x1P-32ULLK +#define __UHQ_IBIT__ 0 +#define __LLACCUM_IBIT__ 32 +#define __DBL_DECIMAL_DIG__ 17 +#define __DEC_EVAL_METHOD__ 2 +#define __TA_FBIT__ 63 +#define __UDQ_IBIT__ 0 +#define __ORDER_BIG_ENDIAN__ 4321 +#define __ACCUM_EPSILON__ 0x1P-15K +#define __INTMAX_MAX__ 9223372036854775807LL +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __FLT_DENORM_MIN__ 1.4012984643248171e-45F +#define __LLFRACT_IBIT__ 0 +#define __INT8_MAX__ 127 +#define __PIC__ 1 +#define __UINT_FAST32_TYPE__ unsigned int +#define __CHAR32_TYPE__ unsigned int +#define __FLT_MAX__ 3.4028234663852886e+38F +#define __USACCUM_FBIT__ 8 +#define __INT32_TYPE__ int +#define __SIZEOF_DOUBLE__ 8 +#define __UFRACT_EPSILON__ 0x1P-16UR +#define __INTMAX_TYPE__ long long int +#define __DEC128_MAX_EXP__ 6145 +#define __ATOMIC_CONSUME 1 +#define __GNUC_MINOR__ 8 +#define __UINTMAX_MAX__ 18446744073709551615ULL +#define __DEC32_MANT_DIG__ 7 +#define __HA_FBIT__ 7 +#define __DBL_MAX_10_EXP__ 308 +#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L +#define __STDC__ 1 +#define __PTRDIFF_TYPE__ int +#define __LLFRACT_MIN__ (-0.5LLR-0.5LLR) +#define __ATOMIC_SEQ_CST 5 +#define __DA_FBIT__ 31 +#define __UINT32_TYPE__ unsigned int +#define __UINTPTR_TYPE__ unsigned int +#define __USA_IBIT__ 16 +#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD +#define __ARM_EABI__ 1 +#define __DEC128_MANT_DIG__ 34 +#define __LDBL_MIN_10_EXP__ (-307) +#define __SIZEOF_LONG_LONG__ 8 +#define __ULACCUM_EPSILON__ 0x1P-32ULK +#define __SACCUM_IBIT__ 8 +#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 +#define __LDBL_DIG__ 15 +#define __FLT_DECIMAL_DIG__ 9 +#define __UINT_FAST16_MAX__ 4294967295U +#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 +#define __ULLFRACT_MAX__ 0XFFFFFFFFFFFFFFFFP-64ULLR +#define __UINT_FAST8_TYPE__ unsigned char +#define _GNU_SOURCE 1 +#define __USFRACT_EPSILON__ 0x1P-8UHR +#define __ULACCUM_FBIT__ 32 +#define __ARM_FEATURE_DSP 1 +#define __QQ_IBIT__ 0 +#define __ATOMIC_ACQ_REL 4 +#define __ATOMIC_RELEASE 3 +#define ANDROID +#endif + +// --- Include directories begin --- // +//C:/Android/ndk/platforms/android-3/arch-arm/usr/include +//C:\Android\ndk\toolchains\arm-linux-androideabi-4.8\prebuilt\windows\bin\../lib/gcc/arm-linux-androideabi/4.8/include +//C:\Android\ndk\toolchains\arm-linux-androideabi-4.8\prebuilt\windows\bin\../lib/gcc/arm-linux-androideabi/4.8/include-fixed +// --- Library directories end --- // + + +// --- Library directories begin --- // +//C:/Android/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.8/armv7-a/ +//C:/Android/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/lib/armv7-a/ +//C:/Android/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.8/ +//C:/Android/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/../lib/gcc/ +//C:/Android/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/lib/ +// --- Library directories begin --- // + diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/EngineRoot.props b/Graphics/GraphicsEngineOpenGL/build/Windows/EngineRoot.props new file mode 100644 index 00000000..02287e9c --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/EngineRoot.props @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..</GraphicsRoot> + <ProjectRoot>..\..</ProjectRoot> + </PropertyGroup> + <PropertyGroup /> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + <BuildMacro Include="ProjectRoot"> + <Value>$(ProjectRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Debug.vgdbsettings b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Debug.vgdbsettings new file mode 100644 index 00000000..3f5b24b1 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Debug.vgdbsettings @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<VisualGDBProjectSettings2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <ConfigurationName>Debug</ConfigurationName> + <Project xsi:type="com.visualgdb.project.android"> + <CustomSourceDirectories> + <Directories /> + <PathStyle>MinGWWindowsSlash</PathStyle> + </CustomSourceDirectories> + <AndroidProjectPath>$(ProjectDir)</AndroidProjectPath> + </Project> + <Build xsi:type="com.visualgdb.build.android"> + <AndroidPlatform>android-19</AndroidPlatform> + <IsDebugConfiguration>true</IsDebugConfiguration> + <JNIOnlyBuild>true</JNIOnlyBuild> + <AdditionalDirectoriesToDeleteOnClean>bin;obj</AdditionalDirectoriesToDeleteOnClean> + <DeleteANTFilesOnClean>false</DeleteANTFilesOnClean> + <DoNotEditAndroidManifest>false</DoNotEditAndroidManifest> + <CustomActions /> + </Build> + <Debug xsi:type="com.visualgdb.debug.android"> + <AdditionalStartupCommands /> + <AdditionalGDBSettings> + <FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications> + <ForceSingleThreadedMode>false</ForceSingleThreadedMode> + <PendingBreakpointsSupported>true</PendingBreakpointsSupported> + <DisableChildRanges>false</DisableChildRanges> + <UseAppleExtensions>false</UseAppleExtensions> + <CanAcceptCommandsWhileRunning>false</CanAcceptCommandsWhileRunning> + <MakeLogFile>false</MakeLogFile> + <IgnoreModuleEventsWhileStepping>true</IgnoreModuleEventsWhileStepping> + <UseRelativePathsOnly>false</UseRelativePathsOnly> + <ExitAction>KillApp</ExitAction> + <Features> + <DisableAutoDetection>false</DisableAutoDetection> + <UseFrameParameter>false</UseFrameParameter> + <SimpleValuesFlagSupported>false</SimpleValuesFlagSupported> + <ListLocalsSupported>false</ListLocalsSupported> + <ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable> + <ThreadInfoSupported>false</ThreadInfoSupported> + <PendingBreakpointsSupported>false</PendingBreakpointsSupported> + <SupportTargetCommand>false</SupportTargetCommand> + </Features> + <DisableDisassembly>false</DisableDisassembly> + <ExamineMemoryWithXCommand>false</ExamineMemoryWithXCommand> + <StepIntoNewInstanceEntry>main</StepIntoNewInstanceEntry> + <ExamineRegistersInRawFormat>true</ExamineRegistersInRawFormat> + </AdditionalGDBSettings> + <LaunchGDBSettings xsi:type="GDBLaunchParametersAndroid" /> + <GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC> + <UseDefaultInstallDir>false</UseDefaultInstallDir> + <RemotePort>5039</RemotePort> + <LocalPort>5039</LocalPort> + <GDBServerStartupTimeout>10000</GDBServerStartupTimeout> + <AdditionalGDBServerStartupDelay>0</AdditionalGDBServerStartupDelay> + <DoubleSlashWorkaround>false</DoubleSlashWorkaround> + <AlreadyRunningDecision>Ask</AlreadyRunningDecision> + <ShowLogCat>true</ShowLogCat> + <EnableThreadNameWatcher>true</EnableThreadNameWatcher> + </Debug> + <CustomBuild> + <PreBuildActions /> + <PostBuildActions /> + <PreCleanActions /> + <PostCleanActions /> + </CustomBuild> + <CustomDebug> + <PreDebugActions /> + <PostDebugActions /> + <BreakMode>Default</BreakMode> + </CustomDebug> + <CustomShortcuts> + <Shortcuts /> + <ShowMessageAfterExecuting>true</ShowMessageAfterExecuting> + </CustomShortcuts> + <UserDefinedVariables /> +</VisualGDBProjectSettings2>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Release.vgdbsettings b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Release.vgdbsettings new file mode 100644 index 00000000..669691f2 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Release.vgdbsettings @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<VisualGDBProjectSettings2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <ConfigurationName>Release</ConfigurationName> + <Project xsi:type="com.visualgdb.project.android"> + <CustomSourceDirectories> + <Directories /> + <PathStyle>MinGWWindowsSlash</PathStyle> + </CustomSourceDirectories> + <AndroidProjectPath>$(ProjectDir)</AndroidProjectPath> + </Project> + <Build xsi:type="com.visualgdb.build.android"> + <AndroidPlatform>android-19</AndroidPlatform> + <IsDebugConfiguration>false</IsDebugConfiguration> + <JNIOnlyBuild>true</JNIOnlyBuild> + <AdditionalDirectoriesToDeleteOnClean>bin;obj</AdditionalDirectoriesToDeleteOnClean> + <DeleteANTFilesOnClean>false</DeleteANTFilesOnClean> + <DoNotEditAndroidManifest>false</DoNotEditAndroidManifest> + <CustomActions /> + </Build> + <Debug xsi:type="com.visualgdb.debug.android"> + <AdditionalStartupCommands /> + <AdditionalGDBSettings> + <FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications> + <ForceSingleThreadedMode>false</ForceSingleThreadedMode> + <PendingBreakpointsSupported>true</PendingBreakpointsSupported> + <DisableChildRanges>false</DisableChildRanges> + <UseAppleExtensions>false</UseAppleExtensions> + <CanAcceptCommandsWhileRunning>false</CanAcceptCommandsWhileRunning> + <MakeLogFile>false</MakeLogFile> + <IgnoreModuleEventsWhileStepping>true</IgnoreModuleEventsWhileStepping> + <UseRelativePathsOnly>false</UseRelativePathsOnly> + <ExitAction>KillApp</ExitAction> + <Features> + <DisableAutoDetection>false</DisableAutoDetection> + <UseFrameParameter>false</UseFrameParameter> + <SimpleValuesFlagSupported>false</SimpleValuesFlagSupported> + <ListLocalsSupported>false</ListLocalsSupported> + <ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable> + <ThreadInfoSupported>false</ThreadInfoSupported> + <PendingBreakpointsSupported>false</PendingBreakpointsSupported> + <SupportTargetCommand>false</SupportTargetCommand> + </Features> + <DisableDisassembly>false</DisableDisassembly> + <ExamineMemoryWithXCommand>false</ExamineMemoryWithXCommand> + <StepIntoNewInstanceEntry>main</StepIntoNewInstanceEntry> + <ExamineRegistersInRawFormat>true</ExamineRegistersInRawFormat> + </AdditionalGDBSettings> + <LaunchGDBSettings xsi:type="GDBLaunchParametersAndroid" /> + <GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC> + <UseDefaultInstallDir>false</UseDefaultInstallDir> + <RemotePort>5039</RemotePort> + <LocalPort>5039</LocalPort> + <GDBServerStartupTimeout>10000</GDBServerStartupTimeout> + <AdditionalGDBServerStartupDelay>0</AdditionalGDBServerStartupDelay> + <DoubleSlashWorkaround>false</DoubleSlashWorkaround> + <AlreadyRunningDecision>Ask</AlreadyRunningDecision> + <ShowLogCat>true</ShowLogCat> + <EnableThreadNameWatcher>true</EnableThreadNameWatcher> + </Debug> + <CustomBuild> + <PreBuildActions /> + <PostBuildActions /> + <PreCleanActions /> + <PostCleanActions /> + </CustomBuild> + <CustomDebug> + <PreDebugActions /> + <PostDebugActions /> + <BreakMode>Default</BreakMode> + </CustomDebug> + <CustomShortcuts> + <Shortcuts /> + <ShowMessageAfterExecuting>true</ShowMessageAfterExecuting> + </CustomShortcuts> + <UserDefinedVariables /> +</VisualGDBProjectSettings2>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.props b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.props new file mode 100644 index 00000000..783f8a0f --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.props @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsEngineOpenGL\include;$(GraphicsRoot)\GraphicsEngineOpenGL\interface;$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\External\glew-1.10.0\include\GL;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup /> + <ItemGroup /> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj new file mode 100644 index 00000000..34fbeeba --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj @@ -0,0 +1,538 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="DbgDLL|ARM"> + <Configuration>DbgDLL</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="DbgDLL|Win32"> + <Configuration>DbgDLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="DbgDLL|x64"> + <Configuration>DbgDLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="RelDLL|ARM"> + <Configuration>RelDLL</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="RelDLL|Win32"> + <Configuration>RelDLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="RelDLL|x64"> + <Configuration>RelDLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{15E346D3-FDE6-4B29-88B7-FCA14DADA501}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>GraphicsEngineOpenGL</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|ARM'" Label="Configuration"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|ARM'" Label="Configuration"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineOpenGL.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineOpenGL.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineOpenGL.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineOpenGL.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineOpenGL.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineOpenGL.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineOpenGL.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsEngineOpenGL.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="..\..\..\..\Shared\build\Windows\Android32d.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|ARM'" Label="PropertySheets"> + <Import Project="..\..\..\..\Shared\build\Windows\Android32d.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="..\..\..\..\Shared\build\Windows\Android32r.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|ARM'" Label="PropertySheets"> + <Import Project="..\..\..\..\Shared\build\Windows\Android32r.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <NMakeForcedIncludes>$(ProjectDir)\Android\gcc_Debug.h;$(NMakeForcedIncludes)</NMakeForcedIncludes> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|ARM'"> + <NMakeForcedIncludes>$(ProjectDir)\Android\gcc_Debug.h;$(NMakeForcedIncludes)</NMakeForcedIncludes> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <NMakeForcedIncludes>$(ProjectDir)\Android\gcc_Release.h;$(NMakeForcedIncludes)</NMakeForcedIncludes> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|ARM'"> + <NMakeForcedIncludes>$(ProjectDir)\Android\gcc_Release.h;$(NMakeForcedIncludes)</NMakeForcedIncludes> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>..\..\src\GraphicsEngineOpenGL.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <Lib> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>..\..\src\GraphicsEngineOpenGL.def</ModuleDefinitionFile> + </Link> + <Lib> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>..\..\src\GraphicsEngineOpenGL.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <Lib> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>..\..\src\GraphicsEngineOpenGL.def</ModuleDefinitionFile> + </Link> + <Lib> + <TargetMachine>MachineX64</TargetMachine> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\..\include\BlendStateGLImpl.h" /> + <ClInclude Include="..\..\include\BufferGLImpl.h" /> + <ClInclude Include="..\..\include\BufferViewGLImpl.h" /> + <ClInclude Include="..\..\include\DeviceContextGLImpl.h" /> + <ClInclude Include="..\..\include\DSStateGLImpl.h" /> + <ClInclude Include="..\..\include\FBOCache.h" /> + <ClInclude Include="..\..\include\GLContextAndroid.h" /> + <ClInclude Include="..\..\include\GLContextState.h" /> + <ClInclude Include="..\..\include\GLContextWindows.h" /> + <ClInclude Include="..\..\include\GLObjectWrapper.h" /> + <ClInclude Include="..\..\include\GLProgram.h" /> + <CustomBuild Include="..\..\include\GLSLDefinitions.h"> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + </CustomBuild> + <ClInclude Include="..\..\include\GLStubs.h" /> + <ClInclude Include="..\..\include\GLTypeConversions.h" /> + <ClInclude Include="..\..\include\HLSL2GLSLConverter.h" /> + <ClInclude Include="..\..\include\RasterizerStateGLImpl.h" /> + <ClInclude Include="..\..\include\RenderDeviceGLImpl.h" /> + <ClInclude Include="..\..\include\RenderDeviceGLESImpl.h" /> + <ClInclude Include="..\..\include\AsyncWritableResource.h" /> + <ClInclude Include="..\..\include\ProgramPipelineCache.h" /> + <ClInclude Include="..\..\include\SamplerGLImpl.h" /> + <ClInclude Include="..\..\include\SwapChainGLImpl.h" /> + <ClInclude Include="..\..\include\TexRegionRender.h" /> + <ClInclude Include="..\..\include\Texture1DArray_OGL.h" /> + <ClInclude Include="..\..\include\Texture1D_OGL.h" /> + <ClInclude Include="..\..\include\Texture2DArray_OGL.h" /> + <ClInclude Include="..\..\include\Texture2D_OGL.h" /> + <ClInclude Include="..\..\include\Texture3D_OGL.h" /> + <ClInclude Include="..\..\include\TextureBaseGL.h" /> + <ClInclude Include="..\..\include\TextureViewGLImpl.h" /> + <ClInclude Include="..\..\include\VAOCache.h" /> + <ClInclude Include="..\..\include\VertexDescGLImpl.h" /> + <ClInclude Include="..\..\include\ShaderGLImpl.h" /> + <ClInclude Include="..\..\include\pch.h" /> + <ClInclude Include="..\..\interface\BlendStateGL.h" /> + <ClInclude Include="..\..\interface\BufferGL.h" /> + <ClInclude Include="..\..\interface\BufferViewGL.h" /> + <ClInclude Include="..\..\interface\DepthStencilStateGL.h" /> + <ClInclude Include="..\..\interface\DeviceContextGL.h" /> + <ClInclude Include="..\..\interface\RasterizerStateGL.h" /> + <ClInclude Include="..\..\interface\RenderDeviceFactoryOpenGL.h" /> + <ClInclude Include="..\..\interface\RenderDeviceGL.h" /> + <ClInclude Include="..\..\interface\RenderDeviceGLES.h" /> + <ClInclude Include="..\..\interface\BaseInterfacesGL.h" /> + <ClInclude Include="..\..\interface\SamplerGL.h" /> + <ClInclude Include="..\..\interface\ShaderGL.h" /> + <ClInclude Include="..\..\interface\SwapChainGL.h" /> + <ClInclude Include="..\..\interface\TextureGL.h" /> + <ClInclude Include="..\..\interface\TextureViewGL.h" /> + <ClInclude Include="..\..\interface\VertexDescriptionGL.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\BlendStateGLImpl.cpp" /> + <ClCompile Include="..\..\src\BufferGLImpl.cpp" /> + <ClCompile Include="..\..\src\BufferViewGLImpl.cpp" /> + <ClCompile Include="..\..\src\DeviceContextGLImpl.cpp" /> + <ClCompile Include="..\..\src\DLLMain.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|ARM'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|ARM'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\DSStateGLImpl.cpp" /> + <ClCompile Include="..\..\src\FBOCache.cpp" /> + <ClCompile Include="..\..\src\GLContextAndroid.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\GLContextState.cpp" /> + <ClCompile Include="..\..\src\GLContextWindows.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|ARM'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|ARM'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\GLObjectWrapper.cpp" /> + <ClCompile Include="..\..\src\GLProgram.cpp" /> + <ClCompile Include="..\..\src\GLStubs.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\GLTypeConversions.cpp" /> + <ClCompile Include="..\..\src\HLSL2GLSLConverter.cpp" /> + <ClCompile Include="..\..\src\RasterizerStateGLImpl.cpp" /> + <ClCompile Include="..\..\src\RenderDeviceGLImpl.cpp" /> + <ClCompile Include="..\..\src\RenderDeviceGLESImpl.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\ProgramPipelineCache.cpp" /> + <ClCompile Include="..\..\src\SamplerGLImpl.cpp" /> + <ClCompile Include="..\..\src\SwapChainGLImpl.cpp" /> + <ClCompile Include="..\..\src\TexRegionRender.cpp" /> + <ClCompile Include="..\..\src\Texture1DArray_OGL.cpp" /> + <ClCompile Include="..\..\src\Texture1D_OGL.cpp" /> + <ClCompile Include="..\..\src\Texture2DArray_OGL.cpp" /> + <ClCompile Include="..\..\src\Texture2D_OGL.cpp" /> + <ClCompile Include="..\..\src\Texture3D_OGL.cpp" /> + <ClCompile Include="..\..\src\TextureBaseGL.cpp" /> + <ClCompile Include="..\..\src\TextureViewGLImpl.cpp" /> + <ClCompile Include="..\..\src\VAOCache.cpp" /> + <ClCompile Include="..\..\src\VertexDescGLImpl.cpp" /> + <ClCompile Include="..\..\src\RenderDeviceFactoryOpenGL.cpp" /> + <ClCompile Include="..\..\src\ShaderGLImpl.cpp" /> + <ClCompile Include="..\..\src\pch.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">Create</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\..\src\GraphicsEngineOpenGL.def" /> + <None Include="jni\Android.mk" /> + <None Include="jni\Application.mk" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\..\Common\build\Windows\Common.vcxproj"> + <Project>{7380f7e6-315f-4b4e-92eb-e6aeee865298}</Project> + <Private>false</Private> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> + <LinkLibraryDependencies>true</LinkLibraryDependencies> + <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> + </ProjectReference> + <ProjectReference Include="..\..\..\..\External\glew-1.10.0\build\Windows\glew_static.vcxproj"> + <Project>{664e6f0d-6784-4760-9565-d54f8eb1edf4}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\..\Platforms\Basic\build\Windows\BasicPlatform.vcxproj"> + <Project>{8ada5f93-7a38-4ad8-b8f5-1ffd4d4f630c}</Project> + <Private>false</Private> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> + <LinkLibraryDependencies>true</LinkLibraryDependencies> + <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> + </ProjectReference> + <ProjectReference Include="..\..\..\..\Platforms\Windows\build\Windows\WindowsPlatform.vcxproj"> + <Project>{58f32677-436b-412a-bbf8-2b1310d82cd8}</Project> + <Private>false</Private> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> + <LinkLibraryDependencies>true</LinkLibraryDependencies> + <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> + </ProjectReference> + <ProjectReference Include="..\..\..\GraphicsEngine\build\Windows\GraphicsEngine.vcxproj"> + <Project>{052dd700-477c-4512-a7f4-b05ebef5c80e}</Project> + <Private>false</Private> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> + <LinkLibraryDependencies>true</LinkLibraryDependencies> + <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> + </ProjectReference> + <ProjectReference Include="..\..\..\GraphicsTools\build\Windows\GraphicsTools.vcxproj"> + <Project>{c6014499-0cf2-43ec-a773-a4e354fb2d74}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj.filters b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj.filters new file mode 100644 index 00000000..03c80428 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj.filters @@ -0,0 +1,306 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="jni"> + <UniqueIdentifier>{658fdc9e-6df5-44d2-9888-cdce02006b44}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\Windows"> + <UniqueIdentifier>{f078efc4-26ba-4803-a3a1-eb22a55e7ada}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\Android"> + <UniqueIdentifier>{10a6ba1a-4ccb-4242-969f-beb04bfd2b65}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Windows"> + <UniqueIdentifier>{ff063a45-e896-4855-8d8d-508a663c5515}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Android"> + <UniqueIdentifier>{564419f6-6302-4533-a5d3-c7e25a40a8af}</UniqueIdentifier> + </Filter> + <Filter Include="Interface"> + <UniqueIdentifier>{f367269b-3ff3-4ab3-917a-e5a7779acefe}</UniqueIdentifier> + </Filter> + <Filter Include="Interface\Windows"> + <UniqueIdentifier>{41dbc56a-4158-4750-bea6-7f28afeb1855}</UniqueIdentifier> + </Filter> + <Filter Include="Interface\Android"> + <UniqueIdentifier>{365f79b5-3f7f-4f71-8b03-d34102794f1d}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\include\VAOCache.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\GLObjectWrapper.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ProgramPipelineCache.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\GLTypeConversions.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\Texture1D_OGL.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\Texture1DArray_OGL.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\Texture2D_OGL.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\Texture2DArray_OGL.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\Texture3D_OGL.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\GLContextAndroid.h"> + <Filter>Header Files\Android</Filter> + </ClInclude> + <ClInclude Include="..\..\include\GLProgram.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\GLContextState.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\AsyncWritableResource.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\GLStubs.h"> + <Filter>Header Files\Android</Filter> + </ClInclude> + <ClInclude Include="..\..\include\BufferGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\BufferViewGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\DSStateGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\SamplerGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ShaderGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\TextureBaseGL.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\VertexDescGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\RenderDeviceGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\RenderDeviceGLESImpl.h"> + <Filter>Header Files\Android</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\RenderDeviceGLES.h"> + <Filter>Interface\Android</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\RenderDeviceGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\BufferGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\BaseInterfacesGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\BufferViewGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\DepthStencilStateGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\SamplerGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\ShaderGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\TextureGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\TextureViewGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\include\TextureViewGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\VertexDescriptionGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\DeviceContextGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\include\DeviceContextGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\RasterizerStateGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\RasterizerStateGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\BlendStateGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\include\BlendStateGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\FBOCache.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\SwapChainGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\include\SwapChainGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\GLContextWindows.h"> + <Filter>Header Files\Windows</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\RenderDeviceFactoryOpenGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\include\pch.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\HLSL2GLSLConverter.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\TexRegionRender.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\VAOCache.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GLObjectWrapper.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\ProgramPipelineCache.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GLTypeConversions.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\Texture1D_OGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\Texture1DArray_OGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\Texture2D_OGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\Texture2DArray_OGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\Texture3D_OGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GLContextWindows.cpp"> + <Filter>Source Files\Windows</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GLContextAndroid.cpp"> + <Filter>Source Files\Android</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GLProgram.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GLContextState.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GLStubs.cpp"> + <Filter>Source Files\Android</Filter> + </ClCompile> + <ClCompile Include="..\..\src\BufferGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\BufferViewGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\DSStateGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\SamplerGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\ShaderGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\TextureBaseGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\VertexDescGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\RenderDeviceGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\TextureViewGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\RenderDeviceGLESImpl.cpp"> + <Filter>Source Files\Android</Filter> + </ClCompile> + <ClCompile Include="..\..\src\DeviceContextGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\RasterizerStateGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\BlendStateGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\FBOCache.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\SwapChainGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\RenderDeviceFactoryOpenGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\pch.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\DLLMain.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\HLSL2GLSLConverter.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\TexRegionRender.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="jni\Application.mk"> + <Filter>jni</Filter> + </None> + <None Include="jni\Android.mk"> + <Filter>jni</Filter> + </None> + <None Include="..\..\src\GraphicsEngineOpenGL.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\..\include\GLSLDefinitions.h"> + <Filter>Header Files</Filter> + </CustomBuild> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Android.mk b/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Android.mk new file mode 100644 index 00000000..521821b3 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Android.mk @@ -0,0 +1,68 @@ +# Android NDK project makefile autogenerated by Premake + +# Preamble +DEPENDENCY_PATH := $(call my-dir) +LOCAL_PATH := $(abspath $(DEPENDENCY_PATH)) +include $(CLEAR_VARS) + + +# Project configuration +LOCAL_MODULE := GraphicsEngineOpenGL +LOCAL_CFLAGS := -std=c++11 -DUSE_GL3_STUB=1 -DENGINE_DLL -DBUILDING_DLL -fvisibility=hidden +LOCAL_CPP_FEATURES := exceptions rtti +LOCAL_STATIC_LIBRARIES += GraphicsEngine-prebuilt AndroidPlatform-prebuilt BasicPlatform-prebuilt GraphicsTools-prebuilt Common-prebuilt ndk_helper native_app_glue + +# Include paths +PROJECT_ROOT := $(LOCAL_PATH)/../../.. +SOLUTION_ROOT := $(PROJECT_ROOT)/../.. +LOCAL_C_INCLUDES := $(PROJECT_ROOT)/include $(PROJECT_ROOT)/interface $(SOLUTION_ROOT)/External + +# Source files +#VisualGDBAndroid: AutoUpdateSourcesInNextLine +LOCAL_SRC_FILES := ../../../src/BlendStateGLImpl.cpp ../../../src/BufferGLImpl.cpp ../../../src/BufferViewGLImpl.cpp ../../../src/DeviceContextGLImpl.cpp ../../../src/DLLMain.cpp ../../../src/DSStateGLImpl.cpp ../../../src/FBOCache.cpp ../../../src/GLContextAndroid.cpp ../../../src/GLContextState.cpp ../../../src/GLContextWindows.cpp ../../../src/GLObjectWrapper.cpp ../../../src/GLProgram.cpp ../../../src/GLStubs.cpp ../../../src/GLTypeConversions.cpp ../../../src/HLSL2GLSLConverter.cpp ../../../src/RasterizerStateGLImpl.cpp ../../../src/RenderDeviceGLImpl.cpp ../../../src/RenderDeviceGLESImpl.cpp ../../../src/ProgramPipelineCache.cpp ../../../src/SamplerGLImpl.cpp ../../../src/SwapChainGLImpl.cpp ../../../src/TexRegionRender.cpp ../../../src/Texture1DArray_OGL.cpp ../../../src/Texture1D_OGL.cpp ../../../src/Texture2DArray_OGL.cpp ../../../src/Texture2D_OGL.cpp ../../../src/Texture3D_OGL.cpp ../../../src/TextureBaseGL.cpp ../../../src/TextureViewGLImpl.cpp ../../../src/VAOCache.cpp ../../../src/VertexDescGLImpl.cpp ../../../src/RenderDeviceFactoryOpenGL.cpp ../../../src/ShaderGLImpl.cpp ../../../src/pch.cpp + +#VisualGDBAndroid: VSExcludeListLocation +VISUALGDB_VS_EXCLUDED_FILES_Release := ../../../src/DLLMain.cpp ../../../src/GLContextWindows.cpp +VISUALGDB_VS_EXCLUDED_FILES_Debug := ../../../src/DLLMain.cpp ../../../src/GLContextWindows.cpp +LOCAL_SRC_FILES := $(filter-out $(VISUALGDB_VS_EXCLUDED_FILES_$(VGDB_VSCONFIG)),$(LOCAL_SRC_FILES)) + +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +# Declare pre-built Common library +LOCAL_MODULE := Common-prebuilt +LOCAL_EXPORT_C_INCLUDES := $(SOLUTION_ROOT)/Common/include $(SOLUTION_ROOT)/Common/interface +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Common/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libCommon.a +include $(PREBUILT_STATIC_LIBRARY) + + +include $(CLEAR_VARS) +# Declare pre-built AndroidPlatform library +LOCAL_MODULE := AndroidPlatform-prebuilt +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Platforms/Android/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libAndroidPlatform.a +LOCAL_EXPORT_C_INCLUDES := $(SOLUTION_ROOT)/Platforms/interface +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Declare pre-built BasicPlatform library +LOCAL_MODULE := BasicPlatform-prebuilt +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Platforms/Basic/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libBasicPlatform.a +include $(PREBUILT_STATIC_LIBRARY) + + +include $(CLEAR_VARS) +# Declare pre-built GraphicsEngine library +LOCAL_MODULE := GraphicsEngine-prebuilt +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Graphics/GraphicsEngine/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libGraphicsEngine.a +LOCAL_EXPORT_C_INCLUDES := $(SOLUTION_ROOT)/Graphics/GraphicsEngine/include $(SOLUTION_ROOT)/Graphics/GraphicsEngine/interface +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +# Declare pre-built Graphics Tools library +LOCAL_MODULE := GraphicsTools-prebuilt +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Graphics/GraphicsTools/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libGraphicsTools.a +LOCAL_EXPORT_C_INCLUDES := $(SOLUTION_ROOT)/Graphics/GraphicsTools/include +include $(PREBUILT_STATIC_LIBRARY) + +$(call import-module,android/ndk_helper) +$(call import-module,android/native_app_glue) diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Application.mk b/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Application.mk new file mode 100644 index 00000000..c7e241e8 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Application.mk @@ -0,0 +1,7 @@ +# Generated by VisualGDB + +DEPENDENCY_PATH := $(call my-dir) +LOCAL_PATH := $(abspath $(DEPENDENCY_PATH)) +include $(LOCAL_PATH)/../../../../../Common/make/AppCommon.mk + +APP_MODULES := GraphicsEngineOpenGL
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h b/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h new file mode 100644 index 00000000..89547eb8 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h @@ -0,0 +1,65 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +namespace Diligent +{ + +class AsyncWritableResource +{ +public: + AsyncWritableResource() : m_PendingMemoryBarriers( 0 ) {} + + void SetPendingMemoryBarriers( Uint32 Barriers ){ m_PendingMemoryBarriers |= Barriers; } + Uint32 GetPendingMemortBarriers(){ return m_PendingMemoryBarriers;} + +private: + friend class GLContextState; + void ResetPendingMemoryBarriers( Uint32 Barriers ){ m_PendingMemoryBarriers = Barriers; } + void ClearPendingMemoryBarriers( Uint32 Barriers ){ m_PendingMemoryBarriers &= ~Barriers; } + + // Buffer barriers: + // GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT + // GL_ELEMENT_ARRAY_BARRIER_BIT + // GL_UNIFORM_BARRIER_BIT + // GL_BUFFER_UPDATE_BARRIER_BIT + // GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT + // GL_SHADER_STORAGE_BARRIER_BIT + + // Texture barriers: + // GL_TEXTURE_FETCH_BARRIER_BIT + // GL_SHADER_IMAGE_ACCESS_BARRIER_BIT + // GL_PIXEL_BUFFER_BARRIER_BIT + // GL_TEXTURE_UPDATE_BARRIER_BIT + + // Misc barriers: + // GL_FRAMEBUFFER_BARRIER_BIT + // GL_TRANSFORM_FEEDBACK_BARRIER_BIT + // GL_ATOMIC_COUNTER_BARRIER_BIT + // GL_QUERY_BUFFER_BARRIER_BIT + + Uint32 m_PendingMemoryBarriers; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/BlendStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BlendStateGLImpl.h new file mode 100644 index 00000000..62874e60 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/BlendStateGLImpl.h @@ -0,0 +1,47 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BaseInterfacesGL.h" +#include "BlendStateGL.h" +#include "BlendStateBase.h" +#include "RenderDevice.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IBlendStateGL interface +class BlendStateGLImpl : public BlendStateBase<IBlendStateGL, IGLDeviceBaseInterface> +{ +public: + typedef BlendStateBase<IBlendStateGL, IGLDeviceBaseInterface> TBlendStateBase; + + BlendStateGLImpl(class IRenderDevice *pDeviceGL, const BlendStateDesc& BlendStateDesc, bool bIsDeviceInternal = false); + ~BlendStateGLImpl(); + + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h new file mode 100644 index 00000000..342dec4d --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h @@ -0,0 +1,69 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BufferGL.h" +#include "BufferBase.h" +#include "GLObjectWrapper.h" +#include "AsyncWritableResource.h" +#include "BaseInterfacesGL.h" +#include "BufferViewGLImpl.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IBufferGL interface +class BufferGLImpl : public BufferBase<IBufferGL, BufferViewGLImpl>, public AsyncWritableResource +{ +public: + typedef BufferBase<IBufferGL, BufferViewGLImpl> TBufferBase; + + BufferGLImpl(class RenderDeviceGLImpl *pDeviceGL, const BufferDesc& BuffDesc, const BufferData &BuffData = BufferData(), bool IsDeviceInternal = false); + ~BufferGLImpl(); + + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void UpdateData(IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData)override; + virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size )override; + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; + virtual void Unmap( IDeviceContext *pContext )override; + + void BufferMemoryBarrier( Uint32 RequiredBarriers, class GLContextState &GLContextState ); + + const GLObjectWrappers::GLBufferObj& GetGLBufferHandle(){ return m_GlBuffer; } + +private: + virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, class IBufferView **ppView, bool bIsDefaultView )override; + + friend class DeviceContextGLImpl; + friend class VAOCache; + + GLObjectWrappers::GLBufferObj m_GlBuffer; + Uint32 m_uiMapTarget; + GLenum m_GLUsageHint; + Bool m_bUseMapWriteDiscardBugWA; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h new file mode 100644 index 00000000..2f7ed835 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h @@ -0,0 +1,56 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BufferViewGL.h" +#include "BaseInterfacesGL.h" +#include "BufferViewBase.h" +#include "RenderDevice.h" +#include "GLObjectWrapper.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IBufferViewGL interface +class BufferViewGLImpl : public BufferViewBase<IBufferViewGL> +{ +public: + typedef BufferViewBase<IBufferViewGL> TBuffViewBase; + + BufferViewGLImpl( class IRenderDevice *pDevice, + class IDeviceContext *pContext, + const struct BufferViewDesc& ViewDesc, + class BufferGLImpl *pBuffer, + bool bIsDefaultView); + + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + const GLObjectWrappers::GLTextureObj& GetTexBufferHandle(){ return m_GLTexBuffer; } + +private: + GLObjectWrappers::GLTextureObj m_GLTexBuffer; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/DSStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DSStateGLImpl.h new file mode 100644 index 00000000..38f8eaff --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/DSStateGLImpl.h @@ -0,0 +1,46 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BaseInterfacesGL.h" +#include "DepthStencilStateGL.h" +#include "DepthStencilStateBase.h" +#include "RenderDevice.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IDepthStencilStateGL interface +class DSStateGLImpl : public DepthStencilStateBase<IDepthStencilStateGL, IGLDeviceBaseInterface> +{ +public: + typedef DepthStencilStateBase<IDepthStencilStateGL, IGLDeviceBaseInterface> TDSStateBase; + + DSStateGLImpl(class IRenderDevice *pDeviceGL, const DepthStencilStateDesc& DepthStencilStateDesc, bool bIsDeviceInternal = false); + ~DSStateGLImpl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h new file mode 100644 index 00000000..08694a9f --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -0,0 +1,97 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "DeviceContextGL.h" +#include "DeviceContextBase.h" +#include "BaseInterfacesGL.h" +#include "GLContextState.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IDeviceContextGL interface +class DeviceContextGLImpl : public DeviceContextBase<IDeviceContextGL> +{ +public: + typedef DeviceContextBase<IDeviceContextGL> TDeviceContextBase; + + DeviceContextGLImpl( class RenderDeviceGLImpl *pDeviceGL ); + + /// Queries the specific interface, see IObject::QueryInterface() for details. + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void SetShaders( IShader **ppShaders, Uint32 NumShadersToSet )override; + + virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override; + + virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )override; + virtual void ClearState()override; + + virtual void SetVertexDescription( IVertexDescription *pVertexDesc )override; + + virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset )override; + + virtual void SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef = 0 )override; + + virtual void SetRasterizerState( IRasterizerState *pRS )override; + + virtual void SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask )override; + + virtual void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight )override; + + virtual void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight )override; + + virtual void SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil )override; + + virtual void Draw( DrawAttribs &DrawAttribs )override; + + virtual void DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )override; + + virtual void ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil)override; + + virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA )override; + + virtual void Flush()override; + + void BindProgramResources( Uint32 &NewMemoryBarriers ); + + GLContextState &GetContextState(){return m_ContextState;} + + void RebindRenderTargets(); + +protected: + friend class BufferGLImpl; + friend class TextureBaseGL; + friend class VertexDescGLImpl; + friend class ShaderGLImpl; + + GLContextState m_ContextState; + +private: + std::vector<class TextureBaseGL*> m_BoundWritableTextures; + std::vector<class BufferGLImpl*> m_BoundWritableBuffers; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/FBOCache.h b/Graphics/GraphicsEngineOpenGL/include/FBOCache.h new file mode 100644 index 00000000..c1e601d8 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/FBOCache.h @@ -0,0 +1,92 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "GraphicsTypes.h" +#include "TextureView.h" +#include "LockHelper.h" +#include "HashUtils.h" +#include "GLObjectWrapper.h" + +namespace Diligent +{ + +class FBOCache +{ +public: + FBOCache(); + ~FBOCache(); + + const GLObjectWrappers::GLFrameBufferObj& GetFBO( Uint32 NumRenderTargets, + ITextureView *ppRenderTargets[], + ITextureView *pDepthStencil, + class GLContextState &ContextState); + void OnReleaseTexture(ITexture *pTexture); + +private: + // This structure is used as the key to find FBO + struct FBOCacheKey + { + // Using pointers is not reliable! + + Uint32 NumRenderTargets; + + // Unique IDs of textures bound as render targets + Diligent::UniqueIdentifier RTIds[MaxRenderTargets]; + TextureViewDesc RTVDescs[MaxRenderTargets]; + + // Unique IDs of texture bound as depth stencil + Diligent::UniqueIdentifier DSId; + TextureViewDesc DSVDesc; + + mutable size_t Hash; + + bool operator == (const FBOCacheKey &Key)const; + + FBOCacheKey() : + NumRenderTargets( 0 ), + DSId(0), + Hash(0) + { + for( int rt = 0; rt < MaxRenderTargets; ++rt ) + RTIds[rt] = 0; + } + }; + + struct FBOCacheKeyHashFunc + { + std::size_t operator() ( const FBOCacheKey& Key )const; + }; + + + friend class RenderDeviceGLImpl; + ThreadingTools::LockFlag m_CacheLockFlag; + std::unordered_map<FBOCacheKey, GLObjectWrappers::GLFrameBufferObj, FBOCacheKeyHashFunc> m_Cache; + + // Multimap that sets up correspondence between unique texture id and all + // FBOs it is used in + std::unordered_multimap<Diligent::UniqueIdentifier, FBOCacheKey> m_TexIdToKey; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h b/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h new file mode 100644 index 00000000..63299daf --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h @@ -0,0 +1,83 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include <EGL/egl.h> +#include <android\native_window.h> + +namespace Diligent +{ + struct ContextInitInfo + { + SwapChainDesc SwapChainAttribs; + void *pNativeWndHandle; + }; + + class GLContext + { + public: + GLContext( const ContextInitInfo &Info, DeviceCaps &DeviceCaps ); + ~GLContext(); + + bool Init( ANativeWindow* window ); + + void SwapBuffers(); + + bool Invalidate(); + + void Suspend(); + EGLint Resume( ANativeWindow* window ); + + const SwapChainDesc& GetSwapChainDesc(){ return SwapChainAttribs_; } + + private: + //EGL configurations + ANativeWindow* window_; + EGLDisplay display_; + EGLSurface surface_; + EGLContext context_; + EGLConfig config_; + + //Screen parameters + int32_t color_size_; + int32_t depth_size_; + int32_t major_version_; + int32_t minor_version_; + + //Flags + bool gles_initialized_; + bool egl_context_initialized_; + bool es3_supported_; + float gl_version_; + bool context_valid_; + + SwapChainDesc SwapChainAttribs_; + + void InitGLES(); + void Terminate(); + bool InitEGLSurface(); + bool InitEGLContext(); + void FillDeviceCaps( DeviceCaps &DeviceCaps ); + }; +} diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h new file mode 100644 index 00000000..cda952e1 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h @@ -0,0 +1,212 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "GraphicsTypes.h" +#include "GLObjectWrapper.h" +#include "UniqueIdentifier.h" + +namespace Diligent +{ + +class GLContextState +{ +public: + GLContextState(class RenderDeviceGLImpl *pDeviceGL); + + void SetProgram( const GLObjectWrappers::GLProgramObj &GLProgram ); + void SetPipeline( const GLObjectWrappers::GLPipelineObj &GLPipeline ); + void BindVAO( const GLObjectWrappers::GLVertexArrayObj &VAO ); + void BindFBO( const GLObjectWrappers::GLFrameBufferObj &FBO ); + void SetActiveTexture( Int32 Index ); + void BindTexture( Int32 Index, GLenum BindTarget, const GLObjectWrappers::GLTextureObj &Tex); + void BindSampler( Uint32 Index, const GLObjectWrappers::GLSamplerObj &GLSampler); + void BindImage( Uint32 Index, class TextureViewGLImpl *pTexView, GLint MipLevel, GLboolean IsLayered, GLint Layer, GLenum Access, GLenum Format ); + void EnsureMemoryBarrier(Uint32 RequiredBarriers, class AsyncWritableResource *pRes = nullptr); + void SetPendingMemoryBarriers( Uint32 PendingBarriers ); + + void EnableDepthTest( Bool bEnable ); + void EnableDepthWrites( Bool bEnable ); + void SetDepthFunc(COMPARISON_FUNCTION CmpFunc); + void EnableStencilTest( Bool bEnable ); + void SetStencilWriteMask( Uint8 StencilWriteMask ); + void SetStencilFunc( GLenum Face, COMPARISON_FUNCTION Func, Int32 Ref, Uint32 Mask ); + void SetStencilOp( GLenum Face, STENCIL_OP StencilFailOp, STENCIL_OP StencilDepthFailOp, STENCIL_OP StencilPassOp ); + + void SetFillMode( FILL_MODE FillMode ); + void SetCullMode( CULL_MODE CullMode ); + void SetFrontFace( Bool FrontCounterClockwise ); + void SetDepthBias( float DepthBias, float fSlopeScaledDepthBias ); + void SetDepthClamp( Bool bEnableDepthClamp ); + void EnableScissorTest( Bool bEnableScissorTest ); + + void SetBlendState(const BlendStateDesc &BSDsc, const float *BlendFactors, Uint32 SampleMask); + + Bool GetDepthWritesEnabled(){ return m_DepthWritesEnableState; } + Bool GetScissorTestEnabled(){ return m_RSState.ScissorTestEnable; } + void GetColorWriteMask( Uint32 RTIndex, Uint32 &WriteMask, Bool &bIsIndependent ); + void SetColorWriteMask( Uint32 RTIndex, Uint32 WriteMask, Bool bIsIndependent ); + +private: + // It is unsafe to use GL handle to keep track of bound objects + // When an object is released, GL is free to reuse its handle for + // the new created objects. + // Even using pointers is not safe as when an object is created, + // the system can reuse the same address + // The safest way is to keep global unique ID for all objects + + Diligent::UniqueIdentifier m_GLProgId; + Diligent::UniqueIdentifier m_GLPipelineId; + Diligent::UniqueIdentifier m_VAOId; + Diligent::UniqueIdentifier m_FBOId; + std::vector< Diligent::UniqueIdentifier > m_BoundTextures; + std::vector< Diligent::UniqueIdentifier > m_BoundSamplers; + struct BoundImageInfo + { + Diligent::UniqueIdentifier InterfaceID; + GLint MipLevel; + GLboolean IsLayered; + GLint Layer; + GLenum Access; + GLenum Format; + + BoundImageInfo( Diligent::UniqueIdentifier _UniqueID = 0, + GLint _MipLevel = 0, + GLboolean _IsLayered = 0, + GLint _Layer = 0, + GLenum _Access = 0, + GLenum _Format = 0) : + InterfaceID (_UniqueID ), + MipLevel (_MipLevel ), + IsLayered (_IsLayered), + Layer (_Layer ), + Access (_Access ), + Format (_Format ) + {} + + bool operator==(const BoundImageInfo &rhs)const + { + return InterfaceID == rhs.InterfaceID && + MipLevel == rhs.MipLevel && + IsLayered == rhs.IsLayered && + Layer == rhs.Layer && + Access == rhs.Access && + Format == rhs.Format; + } + }; + std::vector< BoundImageInfo > m_pBoundImages; + Uint32 m_PendingMemoryBarriers; + + class EnableStateHelper + { + public: + enum class ENABLE_STATE + { + UNKNOWN, + ENABLED, + DISABLED + }; + + EnableStateHelper() : m_EnableState( ENABLE_STATE::UNKNOWN ) {} + bool operator == (bool bEnabled)const + { + return bEnabled && m_EnableState == ENABLE_STATE::ENABLED || + !bEnabled && m_EnableState == ENABLE_STATE::DISABLED; + } + bool operator != (bool bEnabled) const + { + return !(*this == bEnabled); + } + + const EnableStateHelper& operator = (bool bEnabled) + { + m_EnableState = bEnabled ? ENABLE_STATE::ENABLED : ENABLE_STATE::DISABLED; + return *this; + } + + operator bool()const + { + return m_EnableState == ENABLE_STATE::ENABLED; + } + + private: + ENABLE_STATE m_EnableState; + }; + EnableStateHelper m_DepthEnableState; + EnableStateHelper m_DepthWritesEnableState; + COMPARISON_FUNCTION m_DepthCmpFunc; + EnableStateHelper m_StencilTestEnableState; + Uint8 m_StencilReadMask; + Uint8 m_StencilWriteMask; + struct StencilOpState + { + COMPARISON_FUNCTION Func; + STENCIL_OP StencilFailOp; + STENCIL_OP StencilDepthFailOp; + STENCIL_OP StencilPassOp; + Int32 Ref; + Uint32 Mask; + StencilOpState() : + Func( COMPARISON_FUNC_UNKNOW ), + StencilFailOp(STENCIL_OP_UNDEFINED), + StencilDepthFailOp( STENCIL_OP_UNDEFINED ), + StencilPassOp( STENCIL_OP_UNDEFINED ), + Ref( -1 ), + Mask( -1 ) + {} + }m_StencilOpState[2]; + + struct RasterizerGLState + { + FILL_MODE FillMode; + CULL_MODE CullMode; + EnableStateHelper FrontCounterClockwise; + float fDepthBias; + float fSlopeScaledDepthBias; + EnableStateHelper DepthClampEnable; + EnableStateHelper ScissorTestEnable; + RasterizerGLState() : + FillMode(FILL_MODE_UNDEFINED), + CullMode(CULL_MODE_UNDEFINED), + fDepthBias( std::numeric_limits<float>::max() ), + fSlopeScaledDepthBias( std::numeric_limits<float>::max() ) + {} + }m_RSState; + + struct ContextCaps + { + bool bFillModeSelectionSupported; + GLint m_iMaxCombinedTexUnits; + ContextCaps() : + bFillModeSelectionSupported(True), + m_iMaxCombinedTexUnits(0) + {} + }m_Caps; + + Uint32 m_ColorWriteMasks[MaxRenderTargets]; + EnableStateHelper m_bIndependentWriteMasks; + Int32 m_iActiveTexture; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h b/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h new file mode 100644 index 00000000..a134d831 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h @@ -0,0 +1,49 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +namespace Diligent +{ + + struct ContextInitInfo + { + SwapChainDesc SwapChainAttribs; + void *pNativeWndHandle; + }; + + class GLContext + { + public: + GLContext( const ContextInitInfo &Info, struct DeviceCaps &DeviceCaps ); + ~GLContext(); + void SwapBuffers(); + + const SwapChainDesc& GetSwapChainDesc(){ return m_SwapChainAttribs; } + + private: + HGLRC m_Context; + HDC m_WindowHandleToDeviceContext; + SwapChainDesc m_SwapChainAttribs; + }; +} diff --git a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h new file mode 100644 index 00000000..21710d4f --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h @@ -0,0 +1,195 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "UniqueIdentifier.h" + +namespace GLObjectWrappers +{ + +template<class CreateReleaseHelperType> +class GLObjWrapper +{ +public: + GLObjWrapper(bool CreateObject, CreateReleaseHelperType CreateReleaseHelper = CreateReleaseHelperType()) : + m_uiHandle(0), + m_CreateReleaseHelper(CreateReleaseHelper) + { + if( CreateObject ) + { + Create(); + if(!m_uiHandle) + { + std::string ErrorStr("Failed to create "); + ErrorStr += m_CreateReleaseHelper.Name; + ErrorStr += " object"; + LOG_ERROR_AND_THROW(ErrorStr.c_str()); + } + } + } + + ~GLObjWrapper() + { + Release(); + } + + GLObjWrapper(GLObjWrapper&& Wrapper) : + m_uiHandle(Wrapper.m_uiHandle), + m_CreateReleaseHelper( std::move( Wrapper.m_CreateReleaseHelper ) ), + m_UniqueId( std::move(Wrapper.m_UniqueId) ) + { + Wrapper.m_uiHandle = 0; + } + + GLObjWrapper& operator = (GLObjWrapper&& Wrapper) + { + Release(); + m_uiHandle = Wrapper.m_uiHandle; + Wrapper.m_uiHandle = 0; + m_CreateReleaseHelper = std::move( Wrapper.m_CreateReleaseHelper ); + m_UniqueId = std::move(Wrapper.m_UniqueId); + return *this; + } + + void Create() + { + VERIFY(m_uiHandle == 0, "GL object is already initialized"); + Release(); + m_CreateReleaseHelper.Create(m_uiHandle); + VERIFY(m_uiHandle, "Failed to initialize GL object" ); + } + + void Release() + { + if( m_uiHandle ) + { + m_CreateReleaseHelper.Release(m_uiHandle); + m_uiHandle = 0; + } + } + + Diligent::UniqueIdentifier GetUniqueID()const + { + // This unique ID is used to unambiguously identify the object for + // tracking purposes. + // Niether GL handle nor pointer could be safely used for this purpose + // as both GL reuses released handles and the OS reuses released pointers + return m_UniqueId.GetID(); + } + + operator GLuint()const{return m_uiHandle;} + +private: + GLObjWrapper(const GLObjWrapper&); + GLObjWrapper& operator = (const GLObjWrapper&); + + GLuint m_uiHandle; + CreateReleaseHelperType m_CreateReleaseHelper; + + // Have separate counter for every type of wrappers + Diligent::UniqueIdHelper<CreateReleaseHelperType> m_UniqueId; +}; + +class GLBufferObjCreateReleaseHelper +{ +public: + static void Create(GLuint &BuffObj){ glGenBuffers (1, &BuffObj); } + static void Release(GLuint BuffObj){ glDeleteBuffers(1, &BuffObj); } + static const char *Name; +}; +typedef GLObjWrapper<GLBufferObjCreateReleaseHelper> GLBufferObj; + + +class GLProgramObjCreateReleaseHelper +{ +public: + static void Create(GLuint &ProgObj){ ProgObj = glCreateProgram(); } + static void Release(GLuint ProgObj){ glDeleteProgram(ProgObj); } + static const char *Name; +}; +typedef GLObjWrapper<GLProgramObjCreateReleaseHelper> GLProgramObj; + + +class GLShaderObjCreateReleaseHelper +{ +public: + GLShaderObjCreateReleaseHelper(GLenum ShaderType) : m_ShaderType(ShaderType){} + void Create(GLuint &ShaderObj){ ShaderObj = glCreateShader(m_ShaderType); } + void Release(GLuint ShaderObj){ glDeleteShader(ShaderObj); } + static const char *Name; +private: + GLenum m_ShaderType; +}; +typedef GLObjWrapper<GLShaderObjCreateReleaseHelper> GLShaderObj; + + +class GLPipelineObjCreateReleaseHelper +{ +public: + void Create(GLuint &Pipeline) { glGenProgramPipelines(1, &Pipeline); } + void Release(GLuint Pipeline) { glDeleteProgramPipelines(1, &Pipeline); } + static const char *Name; +}; +typedef GLObjWrapper<GLPipelineObjCreateReleaseHelper> GLPipelineObj; + + +class GLVAOCreateReleaseHelper +{ +public: + void Create(GLuint &VAO) { glGenVertexArrays(1, &VAO); } + void Release(GLuint VAO) { glDeleteVertexArrays(1, &VAO); } + static const char *Name; +}; +typedef GLObjWrapper<GLVAOCreateReleaseHelper> GLVertexArrayObj; + + +class GLTextureCreateReleaseHelper +{ +public: + void Create(GLuint &Tex) { glGenTextures(1, &Tex); } + void Release(GLuint Tex) { glDeleteTextures(1, &Tex); } + static const char *Name; +}; +typedef GLObjWrapper<GLTextureCreateReleaseHelper> GLTextureObj; + +class GLSamplerCreateReleaseHelper +{ +public: + void Create(GLuint &Sampler) { glGenSamplers(1, &Sampler); } + void Release(GLuint Sampler) { glDeleteSamplers(1, &Sampler); } + static const char *Name; +}; +typedef GLObjWrapper<GLSamplerCreateReleaseHelper> GLSamplerObj; + + +class GLFBOCreateReleaseHelper +{ +public: + void Create(GLuint &FBO) { glGenFramebuffers(1, &FBO); } + void Release(GLuint FBO) { glDeleteFramebuffers(1, &FBO); } + static const char *Name; +}; +typedef GLObjWrapper<GLFBOCreateReleaseHelper> GLFrameBufferObj; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h new file mode 100644 index 00000000..96206374 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h @@ -0,0 +1,114 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once +#include "GLObjectWrapper.h" + +#ifdef _DEBUG +# define VERIFY_RESOURCE_BINDINGS +#endif + +namespace Diligent +{ + + class GLProgram : public GLObjectWrappers::GLProgramObj + { + public: + GLProgram( bool CreateObject ); + GLProgram( GLProgram&& Program ); + + void LoadUniforms(); + + struct GLProgramVariableBase + { + GLProgramVariableBase( const Char* _Name ) : + Name( _Name ) + {} + + String Name; + RefCntAutoPtr<IDeviceObject> pResource; + }; + + struct UniformBufferInfo : GLProgramVariableBase + { + UniformBufferInfo(const Char* _Name, GLint _Index) : + GLProgramVariableBase(_Name), + Index(_Index) + {} + + GLuint Index; + }; + std::vector<UniformBufferInfo>& GetUniformBlocks(){ return m_UniformBlocks; } + + struct SamplerInfo : GLProgramVariableBase + { + SamplerInfo(const Char* _Name, GLint _Location, GLenum _Type) : + GLProgramVariableBase(_Name), + Location(_Location), + Type(_Type) + {} + GLint Location; + GLenum Type; + }; + std::vector<SamplerInfo>& GetSamplers(){ return m_Samplers; } + + struct ImageInfo : GLProgramVariableBase + { + ImageInfo(const Char* _Name, GLint _BindingPoint, GLenum _Type) : + GLProgramVariableBase(_Name), + BindingPoint(_BindingPoint), + Type(_Type) + {} + + GLint BindingPoint; + GLenum Type; + }; + std::vector<ImageInfo>& GetImages(){ return m_Images; } + + struct StorageBlockInfo : GLProgramVariableBase + { + StorageBlockInfo(const Char* _Name, GLint _Binding) : + GLProgramVariableBase(_Name), + Binding(_Binding) + {} + + GLint Binding; + }; + std::vector<StorageBlockInfo>& GetStorageBlocks(){ return m_StorageBlocks; } + + void BindResources(IResourceMapping *pResourceMapping, Uint32 Flags); + +#ifdef VERIFY_RESOURCE_BINDINGS + void dbgVerifyResourceBindings(); +#endif + + private: + GLProgram( const GLProgram& Program ); + const GLProgram& operator = (const GLProgram& Program); + std::vector<UniformBufferInfo> m_UniformBlocks; + std::vector< SamplerInfo > m_Samplers; + std::vector< ImageInfo > m_Images; + std::vector< StorageBlockInfo > m_StorageBlocks; + // When adding new member DO NOT FORGET TO UPDATE GLProgram( GLProgram&& Program )!!! + }; +} diff --git a/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions.h b/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions.h new file mode 100644 index 00000000..b83c29b2 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions.h @@ -0,0 +1,957 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#ifndef _GLSL_DEFINITIONS_ +#define _GLSL_DEFINITIONS_ + +#define GLSL + +#define float4 vec4 +#define float3 vec3 +#define float2 vec2 + +#define int4 ivec4 +#define int3 ivec3 +#define int2 ivec2 + +#define uint4 uvec4 +#define uint3 uvec3 +#define uint2 uvec2 + +#define bool4 bvec4 +#define bool3 bvec3 +#define bool2 bvec2 + +// OpenGL matrices in GLSL are always as column-major +// (this is not related to how they are stored) +#define float2x2 mat2x2 +#define float2x3 mat3x2 +#define float2x4 mat4x2 + +#define float3x2 mat2x3 +#define float3x3 mat3x3 +#define float3x4 mat4x3 + +#define float4x2 mat2x4 +#define float4x3 mat3x4 +#define float4x4 mat4x4 +#define matrix mat4x4 + +#define static + +#define SamplerState int +#define SamplerComparisonState int + +// https://www.opengl.org/wiki/Memory_Model#Incoherent_memory_access +// Shared variable access uses the rules for incoherent memory access. +// This means that the user must perform certain synchronization in +// order to ensure that shared variables are visible. +// At the same time, shared variables are all implicitly declared coherent, +// so one don't need to (and can't) use that qualifier. +#define groupshared shared + +#ifdef FRAGMENT_SHADER +# define ddx dFdx +# define ddy dFdy +#else +# define ddx(x) (x) // GLSL compiler fails when it sees derivatives +# define ddy(x) (x) // in any shader but fragment +#endif + +#define ddx_coarse ddx +#define ddy_coarse ddy +#define ddx_fine ddx +#define ddy_fine ddy + +#define mul(a, b) ((a)*(b)) +#define frac fract +#define atan2 atan +#define rsqrt inversesqrt +#define fmod mod +#define lerp mix +#define dst distance +#define countbits bitCount +#define firstbithigh findMSB +#define firstbitlow findLSB +#define reversebits bitfieldReverse + +float rcp( float x ){ return 1.0 / x; } +vec2 rcp( vec2 x ){ return vec2(1.0,1.0) / x; } +vec3 rcp( vec3 x ){ return vec3(1.0,1.0,1.0) / x; } +vec4 rcp( vec4 x ){ return vec4(1.0,1.0,1.0,1.0) / x; } + +float saturate( float x ){ return clamp( x, 0.0, 1.0 ); } +vec2 saturate( vec2 x ){ return clamp( x, vec2(0.0, 0.0), vec2(1.0, 1.0) ); } +vec3 saturate( vec3 x ){ return clamp( x, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0) ); } +vec4 saturate( vec4 x ){ return clamp( x, vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0) ); } + +void sincos( float x, out float s, out float c ){ s = sin( x ); c = cos( x ); } +void sincos( vec2 x, out vec2 s, out vec2 c ){ s = sin( x ); c = cos( x ); } +void sincos( vec3 x, out vec3 s, out vec3 c ){ s = sin( x ); c = cos( x ); } +void sincos( vec4 x, out vec4 s, out vec4 c ){ s = sin( x ); c = cos( x ); } + + +// Bit conversion operations + +float asfloat( float x ){ return x; } +vec2 asfloat( vec2 x ){ return x; } +vec3 asfloat( vec3 x ){ return x; } +vec4 asfloat( vec4 x ){ return x; } + +float asfloat( int x ){ return intBitsToFloat(x); } +vec2 asfloat( ivec2 x ){ return intBitsToFloat(x); } +vec3 asfloat( ivec3 x ){ return intBitsToFloat(x); } +vec4 asfloat( ivec4 x ){ return intBitsToFloat(x); } + +float asfloat( uint x ){ return uintBitsToFloat(x); } +vec2 asfloat( uvec2 x ){ return uintBitsToFloat(x); } +vec3 asfloat( uvec3 x ){ return uintBitsToFloat(x); } +vec4 asfloat( uvec4 x ){ return uintBitsToFloat(x); } + + +int asint( int x ){ return x; } +ivec2 asint( ivec2 x ){ return x; } +ivec3 asint( ivec3 x ){ return x; } +ivec4 asint( ivec4 x ){ return x; } + +int asint( uint x ){ return int(x); } +ivec2 asint( uvec2 x ){ return ivec2(x); } +ivec3 asint( uvec3 x ){ return ivec3(x); } +ivec4 asint( uvec4 x ){ return ivec4(x); } + +int asint( float x ){ return floatBitsToInt(x); } +ivec2 asint( vec2 x ){ return floatBitsToInt(x); } +ivec3 asint( vec3 x ){ return floatBitsToInt(x); } +ivec4 asint( vec4 x ){ return floatBitsToInt(x); } + + +uint asuint( uint x ){ return x; } +uvec2 asuint( uvec2 x ){ return x; } +uvec3 asuint( uvec3 x ){ return x; } +uvec4 asuint( uvec4 x ){ return x; } + +uint asuint( int x ){ return uint(x); } +uvec2 asuint( ivec2 x ){ return uvec2(x); } +uvec3 asuint( ivec3 x ){ return uvec3(x); } +uvec4 asuint( ivec4 x ){ return uvec4(x); } + +uint asuint( float x ){ return floatBitsToUint(x); } +uvec2 asuint( vec2 x ){ return floatBitsToUint(x); } +uvec3 asuint( vec3 x ){ return floatBitsToUint(x); } +uvec4 asuint( vec4 x ){ return floatBitsToUint(x); } + + +float f16tof32( uint u1 ) +{ + return unpackHalf2x16( u1 ).x; +} +vec2 f16tof32( uvec2 u2 ) +{ + uint u2PackedHalf = (u2.x & 0x0ffffu) | ((u2.y & 0x0ffffu) << 16u); + return unpackHalf2x16( u2PackedHalf ); +} +vec3 f16tof32( uvec3 u3 ) +{ + return vec3( f16tof32( u3.xy ), f16tof32( u3.z ) ); +} +vec4 f16tof32( uvec4 u4 ) +{ + return vec4( f16tof32( u4.xy ), f16tof32( u4.zw ) ); +} +float f16tof32( int i1 ){ return f16tof32( uint ( i1 ) ); } +vec2 f16tof32( ivec2 i2 ){ return f16tof32( uvec2( i2 ) ); } +vec3 f16tof32( ivec3 i3 ){ return f16tof32( uvec3( i3 ) ); } +vec4 f16tof32( ivec4 i4 ){ return f16tof32( uvec4( i4 ) ); } + +uint f32tof16( float f ) +{ + return packHalf2x16( vec2( f, 0.0 ) ) & 0x0ffffu; +} +uvec2 f32tof16( vec2 f2 ) +{ + uint u2PackedHalf = packHalf2x16( f2 ); + return uvec2( u2PackedHalf & 0x0ffffu, u2PackedHalf >> 16u ); +} +uvec3 f32tof16( vec3 f3 ) +{ + return uvec3( f32tof16( f3.xy ), f32tof16( f3.z ) ); +} +uvec4 f32tof16( vec4 f4 ) +{ + return uvec4( f32tof16( f4.xy ), f32tof16( f4.zw ) ); +} + +#ifndef GL_ES // double is not supported on GLES +double asdouble(uint lowbits, uint highbits) +{ + return packDouble2x32( uvec2( lowbits, highbits ) ); +} +#endif + + +// Floating point functions + +bool isfinite( float x ) +{ + return !isinf( x ) && !isnan( x ); +} + +bool2 isfinite( vec2 f2 ) +{ + return bool2( isfinite( f2.x ), isfinite( f2.y ) ); +} + +bool3 isfinite( vec3 f3 ) +{ + return bool3( isfinite( f3.xy ), isfinite( f3.z ) ); +} + +bool4 isfinite( vec4 f4 ) +{ + return bool4( isfinite( f4.xyz ), isfinite( f4.w ) ); +} + +#ifndef GL_ES + float noise( float x ){ return noise1( x ); } + vec2 noise( vec2 x ){ return noise2( x ); } + vec3 noise( vec3 x ){ return noise3( x ); } + vec4 noise( vec4 x ){ return noise4( x ); } +#else + float noise( float x ){ return 0.0; } + vec2 noise( vec2 x ){ return vec2(0.0, 0.0); } + vec3 noise( vec3 x ){ return vec3(0.0, 0.0, 0.0); } + vec4 noise( vec4 x ){ return vec4(0.0, 0.0, 0.0, 0.0); } +#endif + +float log10( float x ) +{ + return log( x ) / log( 10.0 ); +} +vec2 log10( vec2 x ) +{ + float _lg10 = log( 10.0 ); + return log( x ) / vec2(_lg10, _lg10); +} +vec3 log10( vec3 x ) +{ + float _lg10 = log( 10.0 ); + return log( x ) / vec3(_lg10, _lg10, _lg10); +} +vec4 log10( vec4 x ) +{ + float _lg10 = log( 10.0 ); + return log( x ) / vec4(_lg10, _lg10, _lg10, _lg10); +} + + +#ifdef GL_ES +# define mad(a,b,c) ((a)*(b)+(c)) +#else +# define mad fma +#endif + + +// Relational and logical operators +#define Less lessThan +#define LessEqual lessThanEqual +#define Greater greaterThan +#define GreaterEqual greaterThanEqual +#define Equal equal +#define NotEqual notEqual +#define Not not +bool4 And(bool4 L, bool4 R) +{ + return bool4(L.x && R.x, + L.y && R.y, + L.z && R.z, + L.w && R.w); +} +bool3 And(bool3 L, bool3 R) +{ + return bool3(L.x && R.x, + L.y && R.y, + L.z && R.z); +} +bool2 And(bool2 L, bool2 R) +{ + return bool2(L.x && R.x, + L.y && R.y); +} +bool And(bool L, bool R) +{ + return (L && R); +} + + +bool4 Or(bool4 L, bool4 R) +{ + return bool4(L.x || R.x, + L.y || R.y, + L.z || R.z, + L.w || R.w); +} +bool3 Or(bool3 L, bool3 R) +{ + return bool3(L.x || R.x, + L.y || R.y, + L.z || R.z); +} +bool2 Or(bool2 L, bool2 R) +{ + return bool2(L.x || R.x, + L.y || R.y); +} +bool Or(bool L, bool R) +{ + return (L || R); +} + +float4 BoolToFloat( bool4 b4 ) +{ + return float4(b4.x ? 1.0 : 0.0, + b4.y ? 1.0 : 0.0, + b4.z ? 1.0 : 0.0, + b4.w ? 1.0 : 0.0); +} +float3 BoolToFloat( bool3 b3 ) +{ + return float3(b3.x ? 1.0 : 0.0, + b3.y ? 1.0 : 0.0, + b3.z ? 1.0 : 0.0); +} +float2 BoolToFloat( bool2 b2 ) +{ + return float2(b2.x ? 1.0 : 0.0, + b2.y ? 1.0 : 0.0); +} +float BoolToFloat( bool b ) +{ + return b ? 1.0 : 0.0; +} + + +// Synchronization functions + +#ifdef COMPUTE_SHADER + +// https://www.opengl.org/wiki/Memory_Model#Incoherent_memory_access + +// MSDN: GroupMemoryBarrier() blocks execution of all threads +// in a group until all group SHARED accesses have been completed. +void GroupMemoryBarrier() +{ + // OpenGL.org: groupMemoryBarrier() waits on the completion of all memory accesses + // performed by an invocation of a compute shader relative to the same access performed + // by other invocations in the same work group and then returns with no other effect. + + // groupMemoryBarrier() acts like memoryBarrier(), ordering memory writes for all kinds + // of variables, but it only orders read/writes for the current work group. + groupMemoryBarrier(); + + // OpenGL.org: memoryBarrierShared() waits on the completion of + // all memory accesses resulting from the use of SHARED variables + // and then returns with no other effect. + memoryBarrierShared(); +} + +// MSDN: GroupMemoryBarrierWithGroupSync() blocks execution of all +// threads in a group until all memory accesses have been completed +// and all threads in the group have reached this call. +void GroupMemoryBarrierWithGroupSync() +{ + // Issue memory barrier first! + GroupMemoryBarrier(); + barrier(); +} + +// MSDN: DeviceMemoryBarrier() blocks execution of all threads +// in a group until all device memory accesses have been completed. +void DeviceMemoryBarrier() +{ + // Call all memory barriers except for shared memory + + // Do we need to call groupMemoryBarrier() ????? + + // OpenGL.org: memoryBarrierBuffer() waits on the completion of + // all memory accesses resulting from the use of BUFFER variables + // and then returns with no other effect + memoryBarrierBuffer(); + + // OpenGL.org: memoryBarrierImage() waits on the completion of all + // memory accesses resulting from the use of IMAGE variables and then + // returns with no other effect. + memoryBarrierImage(); + + // OpenGL.org: memoryBarrierAtomicCounter() waits on the completion of + // all accesses resulting from the use of ATOMIC COUNTERS and then returns + // with no other effect. + memoryBarrierAtomicCounter(); +} + +// MSDN: DeviceMemoryBarrierWithGroupSync() blocks execution of +// all threads in a group until all device memory accesses have +// been completed and all threads in the group have reached this call. +void DeviceMemoryBarrierWithGroupSync() +{ + DeviceMemoryBarrier(); + barrier(); +} + +// MSDN: AllMemoryBarrier() blocks execution of all threads in a +// group until all memory accesses have been completed. +void AllMemoryBarrier() +{ + // OpenGL.org: memoryBarrier() waits on the completion of ALL + // memory accesses resulting from the use of IMAGE variables or + // ATOMIC COUNTERS and then returns with no other effect. + memoryBarrier(); + // NOTE: nothing is said about buffer memory and shared memory, + // so call memoryBarrierBuffer() and memoryBarrierShared() for safety + + // OpenGL.org: memoryBarrierBuffer() waits on the completion of + // all memory accesses resulting from the use of BUFFER variables + // and then returns with no other effect + memoryBarrierBuffer(); + + // OpenGL.org: memoryBarrierShared() waits on the completion of + // all memory accesses resulting from the use of SHARED variables + // and then returns with no other effect. + memoryBarrierShared(); + + // Call all memory barrier functions. They should have no effect + // if everything is synchronized. + + // OpenGL.org: memoryBarrierImage() waits on the completion of all + // memory accesses resulting from the use of IMAGE variables and then + // returns with no other effect. + memoryBarrierImage(); + + // OpenGL.org: memoryBarrierAtomicCounter() waits on the completion of + // all accesses resulting from the use of ATOMIC COUNTERS and then returns + // with no other effect. + memoryBarrierAtomicCounter(); + + // groupMemoryBarrier waits on the completion of all memory accesses performed + // by an invocation of a compute shader relative to the same access performed by + // other invocations in the same work group and then returns with no other effect. + groupMemoryBarrier(); +} + +// MSDN: AllMemoryBarrierWithGroupSync() blocks execution of all +// threads in a group until all memory accesses have been completed +// and all threads in the group have reached this call. +void AllMemoryBarrierWithGroupSync() +{ + AllMemoryBarrier(); + barrier(); +} + +#else + +void AllMemoryBarrier(){} +void AllMemoryBarrierWithGroupSync(){} +void DeviceMemoryBarrier(){} +void DeviceMemoryBarrierWithGroupSync(){} +void GroupMemoryBarrier(){} +void GroupMemoryBarrierWithGroupSync(){} + +#endif + + +// Type conversion functions + +vec4 _ExpandVector( float x ){ return vec4( x, x, x, x ); } +vec4 _ExpandVector( vec2 f2 ){ return vec4( f2.x, f2.y, 0.0, 1.0 ); } +vec4 _ExpandVector( vec3 f3 ){ return vec4( f3.x, f3.y, f3.z, 1.0 ); } +vec4 _ExpandVector( vec4 f4 ){ return vec4( f4.x, f4.y, f4.z, f4.w ); } + +ivec4 _ExpandVector( int x ){ return ivec4( x, x, x, x ); } +ivec4 _ExpandVector( ivec2 i2 ){ return ivec4( i2.x, i2.y, 0, 0 ); } +ivec4 _ExpandVector( ivec3 i3 ){ return ivec4( i3.x, i3.y, i3.z, 0 ); } +ivec4 _ExpandVector( ivec4 i4 ){ return ivec4( i4.x, i4.y, i4.z, i4.w ); } + +uvec4 _ExpandVector( uint x ){ return uvec4( x, x, x, x ); } +uvec4 _ExpandVector( uvec2 u2 ){ return uvec4( u2.x, u2.y, 0u, 0u ); } +uvec4 _ExpandVector( uvec3 u3 ){ return uvec4( u3.x, u3.y, u3.z, 0u ); } +uvec4 _ExpandVector( uvec4 u4 ){ return uvec4( u4.x, u4.y, u4.z, u4.w ); } + +bvec4 _ExpandVector( bool x ){ return bvec4( x, x, x, x ); } +bvec4 _ExpandVector( bvec2 b2 ){ return bvec4( b2.x, b2.y, false, false ); } +bvec4 _ExpandVector( bvec3 b3 ){ return bvec4( b3.x, b3.y, b3.z, false ); } +bvec4 _ExpandVector( bvec4 b4 ){ return bvec4( b4.x, b4.y, b4.z, b4.w ); } + + +void _TypeConvertStore( out float Dst, in int Src ){ Dst = float( Src ); } +void _TypeConvertStore( out float Dst, in uint Src ){ Dst = float( Src ); } +void _TypeConvertStore( out float Dst, in float Src ){ Dst = float( Src ); } +void _TypeConvertStore( out uint Dst, in int Src ){ Dst = uint( Src ); } +void _TypeConvertStore( out uint Dst, in uint Src ){ Dst = uint( Src ); } +void _TypeConvertStore( out uint Dst, in float Src ){ Dst = uint( Src ); } +void _TypeConvertStore( out int Dst, in int Src ){ Dst = int( Src ); } +void _TypeConvertStore( out int Dst, in uint Src ){ Dst = int( Src ); } +void _TypeConvertStore( out int Dst, in float Src ){ Dst = int( Src ); } + +int _ToInt( int x ) { return int(x); } +int _ToInt( uint x ) { return int(x); } +int _ToInt( float x ){ return int(x); } +int _ToInt( bool x ) { return x ? 1 : 0; } + +float _ToFloat( int x ) { return float(x); } +float _ToFloat( uint x ) { return float(x); } +float _ToFloat( float x ){ return float(x); } +float _ToFloat( bool x ) { return x ? 1.0 : 0.0;} + +uint _ToUint( int x ) { return uint(x); } +uint _ToUint( uint x ) { return uint(x); } +uint _ToUint( float x ){ return uint(x); } +uint _ToUint( bool x ) { return x ? 1u : 0u; } + +bool _ToBool( int x ) { return x != 0 ? true : false; } +bool _ToBool( uint x ) { return x != 0u ? true : false; } +bool _ToBool( float x ){ return x != 0.0 ? true : false; } +bool _ToBool( bool x ) { return x; } + +#define _ToVec2(x,y) vec2(_ToFloat(x), _ToFloat(y)) +#define _ToVec3(x,y,z) vec3(_ToFloat(x), _ToFloat(y), _ToFloat(z)) +#define _ToVec4(x,y,z,w) vec4(_ToFloat(x), _ToFloat(y), _ToFloat(z), _ToFloat(w)) + +#define _ToIvec2(x,y) ivec2(_ToInt(x), _ToInt(y)) +#define _ToIvec3(x,y,z) ivec3(_ToInt(x), _ToInt(y), _ToInt(z)) +#define _ToIvec4(x,y,z,w) ivec4(_ToInt(x), _ToInt(y), _ToInt(z), _ToInt(w)) + +#define _ToUvec2(x,y) uvec2(_ToUint(x), _ToUint(y)) +#define _ToUvec3(x,y,z) uvec3(_ToUint(x), _ToUint(y), _ToUint(z)) +#define _ToUvec4(x,y,z,w) uvec4(_ToUint(x), _ToUint(y), _ToUint(z), _ToUint(w)) + +#define _ToBvec2(x,y) bvec2(_ToBool(x), _ToBool(y)) +#define _ToBvec3(x,y,z) bvec3(_ToBool(x), _ToBool(y), _ToBool(z)) +#define _ToBvec4(x,y,z,w) bvec4(_ToBool(x), _ToBool(y), _ToBool(z), _ToBool(w)) + + +int _ToIvec( uint u1 ){ return _ToInt( u1 ); } +ivec2 _ToIvec( uvec2 u2 ){ return _ToIvec2( u2.x, u2.y ); } +ivec3 _ToIvec( uvec3 u3 ){ return _ToIvec3( u3.x, u3.y, u3.z ); } +ivec4 _ToIvec( uvec4 u4 ){ return _ToIvec4( u4.x, u4.y, u4.z, u4.w ); } + +int _ToIvec( int i1 ){ return i1; } +ivec2 _ToIvec( ivec2 i2 ){ return i2; } +ivec3 _ToIvec( ivec3 i3 ){ return i3; } +ivec4 _ToIvec( ivec4 i4 ){ return i4; } + +int _ToIvec( float f1 ){ return _ToInt( f1 ); } +ivec2 _ToIvec( vec2 f2 ){ return _ToIvec2( f2.x, f2.y ); } +ivec3 _ToIvec( vec3 f3 ){ return _ToIvec3( f3.x, f3.y, f3.z ); } +ivec4 _ToIvec( vec4 f4 ){ return _ToIvec4( f4.x, f4.y, f4.z, f4.w ); } + + +float _ToVec( uint u1 ){ return _ToFloat(u1); } +vec2 _ToVec( uvec2 u2 ){ return _ToVec2( u2.x, u2.y ); } +vec3 _ToVec( uvec3 u3 ){ return _ToVec3( u3.x, u3.y, u3.z ); } +vec4 _ToVec( uvec4 u4 ){ return _ToVec4( u4.x, u4.y, u4.z, u4.w ); } + +float _ToVec( int i1 ){ return _ToFloat(i1); } +vec2 _ToVec( ivec2 i2 ){ return _ToVec2( i2.x, i2.y ); } +vec3 _ToVec( ivec3 i3 ){ return _ToVec3( i3.x, i3.y, i3.z ); } +vec4 _ToVec( ivec4 i4 ){ return _ToVec4( i4.x, i4.y, i4.z, i4.w ); } + +float _ToVec( float f1 ){ return f1; } +vec2 _ToVec( vec2 f2 ){ return f2; } +vec3 _ToVec( vec3 f3 ){ return f3; } +vec4 _ToVec( vec4 f4 ){ return f4; } + + +uint _ToUvec( uint u1 ){ return u1; } +uvec2 _ToUvec( uvec2 u2 ){ return u2; } +uvec3 _ToUvec( uvec3 u3 ){ return u3; } +uvec4 _ToUvec( uvec4 u4 ){ return u4; } + +uint _ToUvec( int i1 ){ return _ToUint( i1 ); } +uvec2 _ToUvec( ivec2 i2 ){ return _ToUvec2( i2.x, i2.y ); } +uvec3 _ToUvec( ivec3 i3 ){ return _ToUvec3( i3.x, i3.y, i3.z ); } +uvec4 _ToUvec( ivec4 i4 ){ return _ToUvec4( i4.x, i4.y, i4.z, i4.w ); } + +uint _ToUvec( float f1 ){ return _ToUint( f1 ); } +uvec2 _ToUvec( vec2 f2 ){ return _ToUvec2( f2.x, f2.y ); } +uvec3 _ToUvec( vec3 f3 ){ return _ToUvec3( f3.x, f3.y, f3.z ); } +uvec4 _ToUvec( vec4 f4 ){ return _ToUvec4( f4.x, f4.y, f4.z, f4.w ); } + + +// TEXTURE FUNCTION STUB MACROS +// https://www.opengl.org/wiki/Sampler_(GLSL) + + +// Texture size queries +// https://www.opengl.org/sdk/docs/man/html/textureSize.xhtml +// textureSize returns the dimensions of level lod (if present) of the texture bound to sampler. +// The components in the return value are filled in, in order, with the width, height and depth +// of the texture. For the array forms, the last component of the return value is the number of +// layers in the texture array. + +//#if !(defined(DESKTOP_GL) && __VERSION__ >= 430) +# define textureQueryLevels(x) 0 // Only supported on 4.3+ +//#endif + +#define GetTex1DDimensions_1(Sampler, Width)\ +{ \ + _TypeConvertStore( Width, textureSize(Sampler, 0) );\ +} + +#define GetTex1DDimensions_3(Sampler, MipLevel, Width, NumberOfMipLevels)\ +{ \ + _TypeConvertStore( Width, textureSize(Sampler, _ToInt(MipLevel)) ); \ + _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) ); \ +} + +#define GetTex1DArrDimensions_2(Sampler, Width, Elements)\ +{ \ + ivec2 i2Size = textureSize(Sampler, 0); \ + _TypeConvertStore( Width, i2Size.x );\ + _TypeConvertStore( Elements, i2Size.y );\ +} + +#define GetTex1DArrDimensions_4(Sampler, MipLevel, Width, Elements, NumberOfMipLevels)\ +{ \ + ivec2 i2Size = textureSize(Sampler, _ToInt(MipLevel)); \ + _TypeConvertStore( Width, i2Size.x ); \ + _TypeConvertStore( Elements, i2Size.y ); \ + _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\ +} + +#define GetTex2DDimensions_2(Sampler, Width, Height)\ +{ \ + ivec2 i2Size = textureSize(Sampler, 0); \ + _TypeConvertStore( Width, i2Size.x ); \ + _TypeConvertStore( Height, i2Size.y ); \ +} + +#define GetTex2DDimensions_4(Sampler, MipLevel, Width, Height, NumberOfMipLevels)\ +{ \ + ivec2 i2Size = textureSize(Sampler, _ToInt(MipLevel) ); \ + _TypeConvertStore( Width, i2Size.x ); \ + _TypeConvertStore( Height, i2Size.y ); \ + _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\ +} + +#define GetTex2DArrDimensions_3(Sampler, Width, Height, Elements)\ +{ \ + ivec3 i3Size = textureSize(Sampler, 0); \ + _TypeConvertStore( Width, i3Size.x ); \ + _TypeConvertStore( Height, i3Size.y ); \ + _TypeConvertStore( Elements,i3Size.z ); \ +} + +#define GetTex2DArrDimensions_5(Sampler, MipLevel, Width, Height, Elements, NumberOfMipLevels)\ +{ \ + ivec3 i3Size = textureSize(Sampler, _ToInt(MipLevel)); \ + _TypeConvertStore( Width, i3Size.x ); \ + _TypeConvertStore( Height, i3Size.y ); \ + _TypeConvertStore( Elements, i3Size.z ); \ + _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\ +} + +#define GetTex3DDimensions_3(Sampler, Width, Height, Depth)\ +{ \ + ivec3 i3Size = textureSize(Sampler, 0); \ + _TypeConvertStore( Width, i3Size.x ); \ + _TypeConvertStore( Height, i3Size.y ); \ + _TypeConvertStore( Depth, i3Size.z ); \ +} + +#define GetTex3DDimensions_5(Sampler, MipLevel, Width, Height, Depth, NumberOfMipLevels)\ +{ \ + ivec3 i3Size = textureSize(Sampler, _ToInt(MipLevel)); \ + _TypeConvertStore( Width, i3Size.x ); \ + _TypeConvertStore( Height, i3Size.y ); \ + _TypeConvertStore( Depth, i3Size.z ); \ + _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\ +} + +#define GetTex2DMSDimensions_3(Sampler, Width, Height, NumberOfSamples)\ +{ \ + ivec2 i2Size = textureSize(Sampler); \ + _TypeConvertStore( Width, i2Size.x ); \ + _TypeConvertStore( Height, i2Size.y ); \ + _TypeConvertStore( NumberOfSamples, 0 );\ +} + +#define GetTex2DMSArrDimensions_4(Sampler, Width, Height, Elements, NumberOfSamples)\ +{ \ + ivec3 i3Size = textureSize(Sampler); \ + _TypeConvertStore( Width, i3Size.x );\ + _TypeConvertStore( Height, i3Size.y );\ + _TypeConvertStore( Elements, i3Size.z );\ + _TypeConvertStore( NumberOfSamples, 0 );\ +} + + +// https://www.opengl.org/sdk/docs/man/html/imageSize.xhtml +// imageSize returns the dimensions of the image bound to image. The components in the +// return value are filled in, in order, with the width, height and depth of the image. +// For the array forms, the last component of the return value is the number of layers +// in the texture array. + +#define GetRWTex1DDimensions_1(Tex, Width)\ +{ \ + _TypeConvertStore( Width, imageSize(Tex) ); \ +} + +#define GetRWTex1DArrDimensions_2(Tex, Width, Elements)\ +{ \ + ivec2 i2Size = imageSize(Tex); \ + _TypeConvertStore( Width, i2Size.x ); \ + _TypeConvertStore( Elements, i2Size.y ); \ +} + +#define GetRWTex2DDimensions_2(Tex, Width, Height)\ +{ \ + ivec2 i2Size = imageSize(Tex); \ + _TypeConvertStore( Width, i2Size.x ); \ + _TypeConvertStore( Height, i2Size.y ); \ +} + +#define GetRWTex2DArrDimensions_3(Tex, Width, Height, Elements)\ +{ \ + ivec3 i3Size = imageSize(Tex); \ + _TypeConvertStore( Width, i3Size.x );\ + _TypeConvertStore( Height, i3Size.y );\ + _TypeConvertStore( Elements, i3Size.z );\ +} + +#define GetRWTex3DDimensions_3(Tex, Width, Height, Depth)\ +{ \ + ivec3 i3Size = imageSize(Tex); \ + _TypeConvertStore( Width, i3Size.x ); \ + _TypeConvertStore( Height, i3Size.y ); \ + _TypeConvertStore( Depth, i3Size.z ); \ +} + + + +// Texture sampling operations + + +// IMPORTANT NOTE ABOUT OFFSET +// Offset parameter to all texture sampling functions must be a constant expression. +// If it is not, the shader will be successfully compiled, HOWEVER the value of Offset +// will silently be zero. +// +// A constant expression in GLSL is defined as follows: +// * A literal value. +// * A const-qualified variable with an explicit initializer (so not a function parameter). +// * The result of the length() function of an array, but only if the array has an explicit size. +// * The result of most operators, so long as all the operands are themselves constant expressions. +// The operators not on this list are any assignment operators (+= and so forth), and the comma operator. +// * The result of a constructor for a type, but only if all of the arguments to the constructor are +// themselves constant expressions. +// * The return value of any built-in function, but only if all of the arguments to the function are +// themselves constant expressions. Opaque Types are never constant expressions. Note that the +// functions dFdx, dFdy, and fwidth will return 0, when used in a context that requires a constant +// expression (such as a const variable initializer). +// +// The list above does not include return value of a function, even when the value is compile-time expression. +// As a result, we cannot use type conversion functions for Offset parameter. + +// In all texture sampling functions, the last component of Coords is used as Dsub and the array layer is specified +// in the second to last component of Coords. (The second component of Coords is unused for 1D shadow lookups.) +// For cube array textures, Dsub is specified as a separate parameter +// mip +#define SampleCmpLevel0Tex1D_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, 0.0, CompareValue), 0.0) +#define SampleCmpLevel0Tex1DArr_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0) +#define SampleCmpLevel0Tex2D_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0) +#define SampleCmpLevel0Tex2DArr_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for sampler2DArrayShadow +#define SampleCmpLevel0TexCube_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for samplerCubeShadow +#define SampleCmpLevel0TexCubeArr_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for samplerCubeArrayShadow + +// mip +#define SampleCmpLevel0Tex1D_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, 0.0, CompareValue), 0.0, int(Offset)) +#define SampleCmpLevel0Tex1DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0, int(Offset)) +#define SampleCmpLevel0Tex2D_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0, ivec2((Offset).xy)) +#define SampleCmpLevel0Tex2DArr_4(Tex, Sampler, Coords, CompareValue, Offset) 0.0 // No textureLodOffset for sampler2DArrayShadow + + +// https://www.opengl.org/sdk/docs/man/html/texture.xhtml - note: there are many mistakes on the page +#ifdef FRAGMENT_SHADER + +# define Sample_2(Tex, Sampler, Coords) texture (Tex, _ToVec(Coords)) +# define Sample_3(Tex, Sampler, Coords, Offset) textureOffset(Tex, _ToVec(Coords), Offset) +# define SampleBias_3(Tex, Sampler, Coords, Bias) texture (Tex, _ToVec(Coords), _ToFloat(Bias)) +# define SampleBias_4(Tex, Sampler, Coords, Bias, Offset) textureOffset(Tex, _ToVec(Coords), Offset, _ToFloat(Bias)) + +# define SampleCmpTex1D_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, 0.0, CompareValue)) +# define SampleCmpTex1DArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue)) +# define SampleCmpTex2D_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue)) +# define SampleCmpTex2DArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue)) +# define SampleCmpTexCube_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue)) +# define SampleCmpTexCubeArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, (Coords).w), _ToFloat(CompareValue)) + +# define SampleCmpTex1D_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, 0.0, CompareValue), int(Offset)) +# define SampleCmpTex1DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), int(Offset)) +# define SampleCmpTex2D_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), ivec2((Offset).xy)) +# define SampleCmpTex2DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue), ivec2((Offset).xy)) + +#else + +// Derivatives are only available in fragment shader. GLSL compiler fails when it +// encounters texture() or textureOffset() instructions in other types of shaders. So +// to let the shader be compiled and to have something meaningful, replace such operations +// with textureLod() and textureLodOffset() + +# define Sample_2(Tex, Sampler, Coords) textureLod (Tex, _ToVec(Coords), 0.0) +# define Sample_3(Tex, Sampler, Coords, Offset) textureLodOffset(Tex, _ToVec(Coords), 0.0, Offset) +# define SampleBias_3(Tex, Sampler, Coords, Bias) textureLod (Tex, _ToVec(Coords), 0.0 + _ToFloat(Bias)) +# define SampleBias_4(Tex, Sampler, Coords, Bias, Offset) textureLodOffset(Tex, _ToVec(Coords), 0.0 + _ToFloat(Bias), Offset) + +# define SampleCmpTex1D_3 SampleCmpLevel0Tex1D_3 +# define SampleCmpTex1DArr_3 SampleCmpLevel0Tex1DArr_3 +# define SampleCmpTex2D_3 SampleCmpLevel0Tex2D_3 +# define SampleCmpTex2DArr_3 SampleCmpLevel0Tex2DArr_3 +# define SampleCmpTexCube_3 SampleCmpLevel0TexCube_3 +# define SampleCmpTexCubeArr_3 SampleCmpLevel0TexCubeArr_3 + +# define SampleCmpTex1D_4 SampleCmpLevel0Tex1D_4 +# define SampleCmpTex1DArr_4 SampleCmpLevel0Tex1DArr_4 +# define SampleCmpTex2D_4 SampleCmpLevel0Tex2D_4 +# define SampleCmpTex2DArr_4 SampleCmpLevel0Tex2DArr_4 + +#endif + +// https://www.opengl.org/sdk/docs/man/html/textureLod.xhtml +#define SampleLevel_3(Tex, Sampler, Coords, Level) textureLod (Tex, _ToVec(Coords), _ToFloat(Level)) +#define SampleLevel_4(Tex, Sampler, Coords, Level, Offset) textureLodOffset(Tex, _ToVec(Coords), _ToFloat(Level), Offset) + +// https://www.opengl.org/sdk/docs/man/html/textureGrad.xhtml +#define SampleGrad_4(Tex, Sampler, Coords, DDX, DDY) textureGrad (Tex, _ToVec(Coords), _ToVec(DDX), _ToVec(DDY)) +#define SampleGrad_5(Tex, Sampler, Coords, DDX, DDY, Offset) textureGradOffset(Tex, _ToVec(Coords), _ToVec(DDX), _ToVec(DDY), Offset) + + +// texelFetch performs a lookup of a single texel from texture coordinate P in the texture +// bound to sampler. The array layer is specified in the last component of P for array forms. +// The lod parameter (if present) specifies the level-of-detail from which the texel will be fetched. +// The sample specifies which sample within the texel will be returned when reading from a multi-sample texure. + +#define LoadTex1D_1(Tex, Location) texelFetch (Tex, _ToInt((Location).x), _ToInt((Location).y)) +#define LoadTex1D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToInt((Location).x), _ToInt((Location).y), int(Offset)) +#define LoadTex1DArr_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xy), _ToInt((Location).z) ) +#define LoadTex1DArr_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xy), _ToInt((Location).z), int(Offset)) +#define LoadTex2D_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xy), _ToInt((Location).z)) +#define LoadTex2D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xy), _ToInt((Location).z), ivec2( (Offset).xy) ) +#define LoadTex2DArr_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xyz), _ToInt((Location).w) ) +#define LoadTex2DArr_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xyz), _ToInt((Location).w), ivec2( (Offset).xy)) +#define LoadTex3D_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xyz), _ToInt((Location).w)) +#define LoadTex3D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xyz), _ToInt((Location).w), ivec3( (Offset).xyz)) +#define LoadTex2DMS_2(Tex, Location, Sample) texelFetch(Tex, _ToIvec( (Location).xy), _ToInt(Sample)) +#define LoadTex2DMS_3(Tex, Location, Sample, Offset)texelFetch(Tex, _ToIvec2( (Location).x + (Offset).x, (Location).y + (Offset).y), int(Sample) ) // No texelFetchOffset for texture2DMS +#define LoadTex2DMSArr_2(Tex, Location, Sample) texelFetch(Tex, _ToIvec( (Location).xyz), _ToInt(Sample)) +#define LoadTex2DMSArr_3(Tex, Location, Sample, Offset)texelFetch(Tex, _ToIvec3( (Location).x + (Offset).x, (Location).y + (Offset).y, (Location).z), int(Sample)) // No texelFetchOffset for texture2DMSArray + +//https://www.opengl.org/sdk/docs/man/html/imageLoad.xhtml +#define LoadRWTex1D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).x) ) +#define LoadRWTex1DArr_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xy) ) +#define LoadRWTex2D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xy) ) +#define LoadRWTex2DArr_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xyz) ) +#define LoadRWTex3D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xyz) ) + + +#define Gather_2(Tex, Sampler, Location) textureGather (Tex, _ToVec(Location)) +#define Gather_3(Tex, Sampler, Location, Offset)textureGatherOffset(Tex, _ToVec(Location), Offset) + +#define GatherCmp_3(Tex, Sampler, Location, CompareVal) textureGather (Tex, _ToVec(Location), _ToFloat(CompareVal)) +#define GatherCmp_4(Tex, Sampler, Location, CompareVal, Offset)textureGatherOffset(Tex, _ToVec(Location), _ToFloat(CompareVal), Offset) + +// Atomic operations +#define InterlockedAddSharedVar_2(dest, value) atomicAdd(dest, value) +#define InterlockedAddSharedVar_3(dest, value, orig_val) orig_val = atomicAdd(dest, value) +#define InterlockedAddImage_2(img, coords, value) imageAtomicAdd(img, _ToIvec(coords), value) +#define InterlockedAddImage_3(img, coords, value, orig_val)orig_val = imageAtomicAdd(img, _ToIvec(coords), value) + +#define InterlockedAndSharedVar_2(dest, value) atomicAnd(dest, value) +#define InterlockedAndSharedVar_3(dest, value, orig_val) orig_val = atomicAnd(dest, value) +#define InterlockedAndImage_2(img, coords, value) imageAtomicAnd(img, _ToIvec(coords), value) +#define InterlockedAndImage_3(img, coords, value, orig_val)orig_val = imageAtomicAnd(img, _ToIvec(coords), value) + +#define InterlockedMaxSharedVar_2(dest, value) atomicMax(dest, value) +#define InterlockedMaxSharedVar_3(dest, value, orig_val) orig_val = atomicMax(dest, value) +#define InterlockedMaxImage_2(img, coords, value) imageAtomicMax(img, _ToIvec(coords), value) +#define InterlockedMaxImage_3(img, coords, value, orig_val)orig_val = imageAtomicMax(img, _ToIvec(coords), value) + +#define InterlockedMinSharedVar_2(dest, value) atomicMin(dest, value) +#define InterlockedMinSharedVar_3(dest, value, orig_val) orig_val = atomicMin(dest, value) +#define InterlockedMinImage_2(img, coords, value) imageAtomicMin(img, _ToIvec(coords), value) +#define InterlockedMinImage_3(img, coords, value, orig_val)orig_val = imageAtomicMin(img, _ToIvec(coords), value) + +#define InterlockedOrSharedVar_2(dest, value) atomicOr(dest, value) +#define InterlockedOrSharedVar_3(dest, value, orig_val) orig_val = atomicOr(dest, value) +#define InterlockedOrImage_2(img, coords, value) imageAtomicOr(img, _ToIvec(coords), value) +#define InterlockedOrImage_3(img, coords, value, orig_val)orig_val = imageAtomicOr(img, _ToIvec(coords), value) + +#define InterlockedXorSharedVar_2(dest, value) atomicXor(dest, value) +#define InterlockedXorSharedVar_3(dest, value, orig_val) orig_val = atomicXor(dest, value) +#define InterlockedXorImage_2(img, coords, value) imageAtomicXor(img, _ToIvec(coords), value) +#define InterlockedXorImage_3(img, coords, value, orig_val)orig_val = imageAtomicXor(img, _ToIvec(coords), value) + +// There is actually no InterlockedExchange() with 2 arguments +#define InterlockedExchangeSharedVar_2(dest, value) atomicExchange(dest, value) +#define InterlockedExchangeSharedVar_3(dest, value, orig_val) orig_val = atomicExchange(dest, value) +#define InterlockedExchangeImage_2(img, coords, value) imageAtomicExchange(img, _ToIvec(coords), value) +#define InterlockedExchangeImage_3(img, coords, value, orig_val)orig_val = imageAtomicExchange(img, _ToIvec(coords), value) + +//uint imageAtomicCompSwap( image img, IVec P, nint compare, nint data); +//void InterlockedCompareExchange( in R dest, in T compare_value, in T value, out T original_value); +#define InterlockedCompareExchangeSharedVar_4(dest, cmp_val, value, orig_val) orig_val = atomicCompSwap(dest, cmp_val, value) +#define InterlockedCompareExchangeImage_4(img, coords, cmp_val, value, orig_val) orig_val = imageAtomicCompSwap(img, _ToIvec(coords), cmp_val, value) + +#define InterlockedCompareStoreSharedVar_3(dest, cmp_val, value) atomicCompSwap(dest, cmp_val, value) +#define InterlockedCompareStoreImage_3(img, coords, cmp_val, value)imageAtomicCompSwap(img, _ToIvec(coords), cmp_val, value) + + +// Swizzling macros +#define _SWIZZLE0 +#define _SWIZZLE1 .x +#define _SWIZZLE2 .xy +#define _SWIZZLE3 .xyz +#define _SWIZZLE4 .xyzw + +// Helper functions + +float2 NormalizedDeviceXYToTexUV( float2 f2ProjSpaceXY ) +{ + return float2(0.5,0.5) + float2(0.5,0.5) * f2ProjSpaceXY.xy; +} + +float NormalizedDeviceZToDepth(float fNDC_Z) +{ + return fNDC_Z * 0.5 + 0.5; // [-1, +1] -> [0, 1] +} + +float DepthToNormalizedDeviceZ(float fDepth) +{ + return fDepth * 2.0 - 1.0; // [0, 1] -> [-1, +1] +} + +#define F3NDC_XYZ_TO_UVD_SCALE float3(0.5, 0.5, 0.5) + +#define NDC_MIN_Z -1.0 // Minimal z in the normalized device space + +#define MATRIX_ELEMENT(mat, row, col) mat[col][row] + +#endif // _GLSL_DEFINITIONS_ diff --git a/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions_inc.h b/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions_inc.h new file mode 100644 index 00000000..bacbdb29 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions_inc.h @@ -0,0 +1,957 @@ +"/* Copyright 2015 Egor Yusov\n" +" * \n" +" * Licensed under the Apache License, Version 2.0 (the \"License\");\n" +" * you may not use this file except in compliance with the License.\n" +" * You may obtain a copy of the License at\n" +" * \n" +" * http://www.apache.org/licenses/LICENSE-2.0\n" +" * \n" +" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" +" * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" +" * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.\n" +" *\n" +" * In no event and under no legal theory, whether in tort (including negligence), \n" +" * contract, or otherwise, unless required by applicable law (such as deliberate \n" +" * and grossly negligent acts) or agreed to in writing, shall any Contributor be\n" +" * liable for any damages, including any direct, indirect, special, incidental, \n" +" * or consequential damages of any character arising as a result of this License or \n" +" * out of the use or inability to use the software (including but not limited to damages \n" +" * for loss of goodwill, work stoppage, computer failure or malfunction, or any and \n" +" * all other commercial damages or losses), even if such Contributor has been advised \n" +" * of the possibility of such damages.\n" +" */\n" +"\n" +"#ifndef _GLSL_DEFINITIONS_\n" +"#define _GLSL_DEFINITIONS_\n" +"\n" +"#define GLSL\n" +"\n" +"#define float4 vec4\n" +"#define float3 vec3\n" +"#define float2 vec2\n" +"\n" +"#define int4 ivec4\n" +"#define int3 ivec3\n" +"#define int2 ivec2\n" +"\n" +"#define uint4 uvec4\n" +"#define uint3 uvec3\n" +"#define uint2 uvec2\n" +"\n" +"#define bool4 bvec4\n" +"#define bool3 bvec3\n" +"#define bool2 bvec2\n" +"\n" +"// OpenGL matrices in GLSL are always as column-major \n" +"// (this is not related to how they are stored)\n" +"#define float2x2 mat2x2\n" +"#define float2x3 mat3x2\n" +"#define float2x4 mat4x2\n" +"\n" +"#define float3x2 mat2x3\n" +"#define float3x3 mat3x3\n" +"#define float3x4 mat4x3\n" +"\n" +"#define float4x2 mat2x4\n" +"#define float4x3 mat3x4\n" +"#define float4x4 mat4x4\n" +"#define matrix mat4x4\n" +"\n" +"#define static\n" +"\n" +"#define SamplerState int\n" +"#define SamplerComparisonState int\n" +"\n" +"// https://www.opengl.org/wiki/Memory_Model#Incoherent_memory_access\n" +"// Shared variable access uses the rules for incoherent memory access. \n" +"// This means that the user must perform certain synchronization in \n" +"// order to ensure that shared variables are visible.\n" +"// At the same time, shared variables are all implicitly declared coherent, \n" +"// so one don\'t need to (and can\'t) use that qualifier.\n" +"#define groupshared shared\n" +"\n" +"#ifdef FRAGMENT_SHADER\n" +"# define ddx dFdx\n" +"# define ddy dFdy\n" +"#else\n" +"# define ddx(x) (x) // GLSL compiler fails when it sees derivatives \n" +"# define ddy(x) (x) // in any shader but fragment\n" +"#endif\n" +"\n" +"#define ddx_coarse ddx\n" +"#define ddy_coarse ddy\n" +"#define ddx_fine ddx\n" +"#define ddy_fine ddy\n" +"\n" +"#define mul(a, b) ((a)*(b))\n" +"#define frac fract\n" +"#define atan2 atan\n" +"#define rsqrt inversesqrt\n" +"#define fmod mod\n" +"#define lerp mix\n" +"#define dst distance\n" +"#define countbits bitCount\n" +"#define firstbithigh findMSB\n" +"#define firstbitlow findLSB\n" +"#define reversebits bitfieldReverse\n" +"\n" +"float rcp( float x ){ return 1.0 / x; }\n" +"vec2 rcp( vec2 x ){ return vec2(1.0,1.0) / x; }\n" +"vec3 rcp( vec3 x ){ return vec3(1.0,1.0,1.0) / x; }\n" +"vec4 rcp( vec4 x ){ return vec4(1.0,1.0,1.0,1.0) / x; }\n" +"\n" +"float saturate( float x ){ return clamp( x, 0.0, 1.0 ); }\n" +"vec2 saturate( vec2 x ){ return clamp( x, vec2(0.0, 0.0), vec2(1.0, 1.0) ); }\n" +"vec3 saturate( vec3 x ){ return clamp( x, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0) ); }\n" +"vec4 saturate( vec4 x ){ return clamp( x, vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0) ); }\n" +"\n" +"void sincos( float x, out float s, out float c ){ s = sin( x ); c = cos( x ); }\n" +"void sincos( vec2 x, out vec2 s, out vec2 c ){ s = sin( x ); c = cos( x ); }\n" +"void sincos( vec3 x, out vec3 s, out vec3 c ){ s = sin( x ); c = cos( x ); }\n" +"void sincos( vec4 x, out vec4 s, out vec4 c ){ s = sin( x ); c = cos( x ); }\n" +"\n" +"\n" +"// Bit conversion operations\n" +"\n" +"float asfloat( float x ){ return x; }\n" +"vec2 asfloat( vec2 x ){ return x; }\n" +"vec3 asfloat( vec3 x ){ return x; }\n" +"vec4 asfloat( vec4 x ){ return x; }\n" +"\n" +"float asfloat( int x ){ return intBitsToFloat(x); }\n" +"vec2 asfloat( ivec2 x ){ return intBitsToFloat(x); }\n" +"vec3 asfloat( ivec3 x ){ return intBitsToFloat(x); }\n" +"vec4 asfloat( ivec4 x ){ return intBitsToFloat(x); }\n" +"\n" +"float asfloat( uint x ){ return uintBitsToFloat(x); }\n" +"vec2 asfloat( uvec2 x ){ return uintBitsToFloat(x); }\n" +"vec3 asfloat( uvec3 x ){ return uintBitsToFloat(x); }\n" +"vec4 asfloat( uvec4 x ){ return uintBitsToFloat(x); }\n" +"\n" +"\n" +"int asint( int x ){ return x; }\n" +"ivec2 asint( ivec2 x ){ return x; }\n" +"ivec3 asint( ivec3 x ){ return x; }\n" +"ivec4 asint( ivec4 x ){ return x; }\n" +"\n" +"int asint( uint x ){ return int(x); }\n" +"ivec2 asint( uvec2 x ){ return ivec2(x); }\n" +"ivec3 asint( uvec3 x ){ return ivec3(x); }\n" +"ivec4 asint( uvec4 x ){ return ivec4(x); }\n" +"\n" +"int asint( float x ){ return floatBitsToInt(x); }\n" +"ivec2 asint( vec2 x ){ return floatBitsToInt(x); }\n" +"ivec3 asint( vec3 x ){ return floatBitsToInt(x); }\n" +"ivec4 asint( vec4 x ){ return floatBitsToInt(x); }\n" +"\n" +"\n" +"uint asuint( uint x ){ return x; }\n" +"uvec2 asuint( uvec2 x ){ return x; }\n" +"uvec3 asuint( uvec3 x ){ return x; }\n" +"uvec4 asuint( uvec4 x ){ return x; }\n" +"\n" +"uint asuint( int x ){ return uint(x); }\n" +"uvec2 asuint( ivec2 x ){ return uvec2(x); }\n" +"uvec3 asuint( ivec3 x ){ return uvec3(x); }\n" +"uvec4 asuint( ivec4 x ){ return uvec4(x); }\n" +"\n" +"uint asuint( float x ){ return floatBitsToUint(x); }\n" +"uvec2 asuint( vec2 x ){ return floatBitsToUint(x); }\n" +"uvec3 asuint( vec3 x ){ return floatBitsToUint(x); }\n" +"uvec4 asuint( vec4 x ){ return floatBitsToUint(x); }\n" +"\n" +"\n" +"float f16tof32( uint u1 )\n" +"{ \n" +" return unpackHalf2x16( u1 ).x; \n" +"}\n" +"vec2 f16tof32( uvec2 u2 )\n" +"{ \n" +" uint u2PackedHalf = (u2.x & 0x0ffffu) | ((u2.y & 0x0ffffu) << 16u);\n" +" return unpackHalf2x16( u2PackedHalf ); \n" +"}\n" +"vec3 f16tof32( uvec3 u3 )\n" +"{ \n" +" return vec3( f16tof32( u3.xy ), f16tof32( u3.z ) );\n" +"}\n" +"vec4 f16tof32( uvec4 u4 )\n" +"{ \n" +" return vec4( f16tof32( u4.xy ), f16tof32( u4.zw ) );\n" +"}\n" +"float f16tof32( int i1 ){ return f16tof32( uint ( i1 ) ); }\n" +"vec2 f16tof32( ivec2 i2 ){ return f16tof32( uvec2( i2 ) ); }\n" +"vec3 f16tof32( ivec3 i3 ){ return f16tof32( uvec3( i3 ) ); }\n" +"vec4 f16tof32( ivec4 i4 ){ return f16tof32( uvec4( i4 ) ); }\n" +"\n" +"uint f32tof16( float f )\n" +"{ \n" +" return packHalf2x16( vec2( f, 0.0 ) ) & 0x0ffffu; \n" +"}\n" +"uvec2 f32tof16( vec2 f2 )\n" +"{ \n" +" uint u2PackedHalf = packHalf2x16( f2 );\n" +" return uvec2( u2PackedHalf & 0x0ffffu, u2PackedHalf >> 16u );\n" +"}\n" +"uvec3 f32tof16( vec3 f3 )\n" +"{\n" +" return uvec3( f32tof16( f3.xy ), f32tof16( f3.z ) );\n" +"}\n" +"uvec4 f32tof16( vec4 f4 )\n" +"{\n" +" return uvec4( f32tof16( f4.xy ), f32tof16( f4.zw ) );\n" +"}\n" +"\n" +"#ifndef GL_ES // double is not supported on GLES\n" +"double asdouble(uint lowbits, uint highbits)\n" +"{\n" +" return packDouble2x32( uvec2( lowbits, highbits ) );\n" +"}\n" +"#endif\n" +"\n" +"\n" +"// Floating point functions\n" +"\n" +"bool isfinite( float x )\n" +"{\n" +" return !isinf( x ) && !isnan( x );\n" +"}\n" +"\n" +"bool2 isfinite( vec2 f2 )\n" +"{\n" +" return bool2( isfinite( f2.x ), isfinite( f2.y ) );\n" +"}\n" +"\n" +"bool3 isfinite( vec3 f3 )\n" +"{\n" +" return bool3( isfinite( f3.xy ), isfinite( f3.z ) );\n" +"}\n" +"\n" +"bool4 isfinite( vec4 f4 )\n" +"{\n" +" return bool4( isfinite( f4.xyz ), isfinite( f4.w ) );\n" +"}\n" +"\n" +"#ifndef GL_ES\n" +" float noise( float x ){ return noise1( x ); }\n" +" vec2 noise( vec2 x ){ return noise2( x ); }\n" +" vec3 noise( vec3 x ){ return noise3( x ); }\n" +" vec4 noise( vec4 x ){ return noise4( x ); }\n" +"#else\n" +" float noise( float x ){ return 0.0; }\n" +" vec2 noise( vec2 x ){ return vec2(0.0, 0.0); }\n" +" vec3 noise( vec3 x ){ return vec3(0.0, 0.0, 0.0); }\n" +" vec4 noise( vec4 x ){ return vec4(0.0, 0.0, 0.0, 0.0); }\n" +"#endif\n" +"\n" +"float log10( float x )\n" +"{\n" +" return log( x ) / log( 10.0 );\n" +"}\n" +"vec2 log10( vec2 x )\n" +"{\n" +" float _lg10 = log( 10.0 );\n" +" return log( x ) / vec2(_lg10, _lg10);\n" +"}\n" +"vec3 log10( vec3 x )\n" +"{\n" +" float _lg10 = log( 10.0 );\n" +" return log( x ) / vec3(_lg10, _lg10, _lg10);\n" +"}\n" +"vec4 log10( vec4 x )\n" +"{\n" +" float _lg10 = log( 10.0 );\n" +" return log( x ) / vec4(_lg10, _lg10, _lg10, _lg10);\n" +"}\n" +"\n" +"\n" +"#ifdef GL_ES\n" +"# define mad(a,b,c) ((a)*(b)+(c))\n" +"#else\n" +"# define mad fma\n" +"#endif\n" +"\n" +"\n" +"// Relational and logical operators\n" +"#define Less lessThan\n" +"#define LessEqual lessThanEqual\n" +"#define Greater greaterThan\n" +"#define GreaterEqual greaterThanEqual\n" +"#define Equal equal\n" +"#define NotEqual notEqual\n" +"#define Not not\n" +"bool4 And(bool4 L, bool4 R)\n" +"{\n" +" return bool4(L.x && R.x,\n" +" L.y && R.y,\n" +" L.z && R.z,\n" +" L.w && R.w);\n" +"}\n" +"bool3 And(bool3 L, bool3 R)\n" +"{\n" +" return bool3(L.x && R.x,\n" +" L.y && R.y,\n" +" L.z && R.z);\n" +"}\n" +"bool2 And(bool2 L, bool2 R)\n" +"{\n" +" return bool2(L.x && R.x,\n" +" L.y && R.y);\n" +"}\n" +"bool And(bool L, bool R)\n" +"{\n" +" return (L && R);\n" +"}\n" +"\n" +"\n" +"bool4 Or(bool4 L, bool4 R)\n" +"{\n" +" return bool4(L.x || R.x,\n" +" L.y || R.y,\n" +" L.z || R.z,\n" +" L.w || R.w);\n" +"}\n" +"bool3 Or(bool3 L, bool3 R)\n" +"{\n" +" return bool3(L.x || R.x,\n" +" L.y || R.y,\n" +" L.z || R.z);\n" +"}\n" +"bool2 Or(bool2 L, bool2 R)\n" +"{\n" +" return bool2(L.x || R.x,\n" +" L.y || R.y);\n" +"}\n" +"bool Or(bool L, bool R)\n" +"{\n" +" return (L || R);\n" +"}\n" +"\n" +"float4 BoolToFloat( bool4 b4 )\n" +"{\n" +" return float4(b4.x ? 1.0 : 0.0,\n" +" b4.y ? 1.0 : 0.0,\n" +" b4.z ? 1.0 : 0.0,\n" +" b4.w ? 1.0 : 0.0);\n" +"}\n" +"float3 BoolToFloat( bool3 b3 )\n" +"{\n" +" return float3(b3.x ? 1.0 : 0.0,\n" +" b3.y ? 1.0 : 0.0,\n" +" b3.z ? 1.0 : 0.0);\n" +"}\n" +"float2 BoolToFloat( bool2 b2 )\n" +"{\n" +" return float2(b2.x ? 1.0 : 0.0,\n" +" b2.y ? 1.0 : 0.0);\n" +"}\n" +"float BoolToFloat( bool b )\n" +"{\n" +" return b ? 1.0 : 0.0;\n" +"}\n" +"\n" +"\n" +"// Synchronization functions\n" +"\n" +"#ifdef COMPUTE_SHADER\n" +"\n" +"// https://www.opengl.org/wiki/Memory_Model#Incoherent_memory_access\n" +"\n" +"// MSDN: GroupMemoryBarrier() blocks execution of all threads \n" +"// in a group until all group SHARED accesses have been completed.\n" +"void GroupMemoryBarrier()\n" +"{\n" +" // OpenGL.org: groupMemoryBarrier() waits on the completion of all memory accesses \n" +" // performed by an invocation of a compute shader relative to the same access performed \n" +" // by other invocations in the same work group and then returns with no other effect.\n" +"\n" +" // groupMemoryBarrier() acts like memoryBarrier(), ordering memory writes for all kinds \n" +" // of variables, but it only orders read/writes for the current work group.\n" +" groupMemoryBarrier();\n" +"\n" +" // OpenGL.org: memoryBarrierShared() waits on the completion of \n" +" // all memory accesses resulting from the use of SHARED variables\n" +" // and then returns with no other effect. \n" +" memoryBarrierShared();\n" +"}\n" +"\n" +"// MSDN: GroupMemoryBarrierWithGroupSync() blocks execution of all \n" +"// threads in a group until all memory accesses have been completed \n" +"// and all threads in the group have reached this call.\n" +"void GroupMemoryBarrierWithGroupSync()\n" +"{\n" +" // Issue memory barrier first!\n" +" GroupMemoryBarrier();\n" +" barrier();\n" +"}\n" +"\n" +"// MSDN: DeviceMemoryBarrier() blocks execution of all threads \n" +"// in a group until all device memory accesses have been completed.\n" +"void DeviceMemoryBarrier()\n" +"{\n" +" // Call all memory barriers except for shared memory\n" +" \n" +" // Do we need to call groupMemoryBarrier() ????? \n" +"\n" +" // OpenGL.org: memoryBarrierBuffer() waits on the completion of \n" +" // all memory accesses resulting from the use of BUFFER variables \n" +" // and then returns with no other effect\n" +" memoryBarrierBuffer();\n" +"\n" +" // OpenGL.org: memoryBarrierImage() waits on the completion of all \n" +" // memory accesses resulting from the use of IMAGE variables and then \n" +" // returns with no other effect. \n" +" memoryBarrierImage();\n" +"\n" +" // OpenGL.org: memoryBarrierAtomicCounter() waits on the completion of \n" +" // all accesses resulting from the use of ATOMIC COUNTERS and then returns \n" +" // with no other effect. \n" +" memoryBarrierAtomicCounter();\n" +"}\n" +"\n" +"// MSDN: DeviceMemoryBarrierWithGroupSync() blocks execution of \n" +"// all threads in a group until all device memory accesses have \n" +"// been completed and all threads in the group have reached this call.\n" +"void DeviceMemoryBarrierWithGroupSync()\n" +"{\n" +" DeviceMemoryBarrier();\n" +" barrier();\n" +"}\n" +"\n" +"// MSDN: AllMemoryBarrier() blocks execution of all threads in a \n" +"// group until all memory accesses have been completed.\n" +"void AllMemoryBarrier()\n" +"{\n" +" // OpenGL.org: memoryBarrier() waits on the completion of ALL \n" +" // memory accesses resulting from the use of IMAGE variables or \n" +" // ATOMIC COUNTERS and then returns with no other effect.\n" +" memoryBarrier();\n" +" // NOTE: nothing is said about buffer memory and shared memory,\n" +" // so call memoryBarrierBuffer() and memoryBarrierShared() for safety\n" +"\n" +" // OpenGL.org: memoryBarrierBuffer() waits on the completion of \n" +" // all memory accesses resulting from the use of BUFFER variables \n" +" // and then returns with no other effect\n" +" memoryBarrierBuffer();\n" +"\n" +" // OpenGL.org: memoryBarrierShared() waits on the completion of \n" +" // all memory accesses resulting from the use of SHARED variables\n" +" // and then returns with no other effect. \n" +" memoryBarrierShared();\n" +"\n" +" // Call all memory barrier functions. They should have no effect\n" +" // if everything is synchronized.\n" +" \n" +" // OpenGL.org: memoryBarrierImage() waits on the completion of all \n" +" // memory accesses resulting from the use of IMAGE variables and then \n" +" // returns with no other effect. \n" +" memoryBarrierImage();\n" +"\n" +" // OpenGL.org: memoryBarrierAtomicCounter() waits on the completion of \n" +" // all accesses resulting from the use of ATOMIC COUNTERS and then returns \n" +" // with no other effect. \n" +" memoryBarrierAtomicCounter();\n" +"\n" +" // groupMemoryBarrier waits on the completion of all memory accesses performed \n" +" // by an invocation of a compute shader relative to the same access performed by \n" +" // other invocations in the same work group and then returns with no other effect.\n" +" groupMemoryBarrier();\n" +"}\n" +"\n" +"// MSDN: AllMemoryBarrierWithGroupSync() blocks execution of all \n" +"// threads in a group until all memory accesses have been completed \n" +"// and all threads in the group have reached this call.\n" +"void AllMemoryBarrierWithGroupSync()\n" +"{\n" +" AllMemoryBarrier();\n" +" barrier();\n" +"}\n" +"\n" +"#else\n" +"\n" +"void AllMemoryBarrier(){}\n" +"void AllMemoryBarrierWithGroupSync(){}\n" +"void DeviceMemoryBarrier(){}\n" +"void DeviceMemoryBarrierWithGroupSync(){}\n" +"void GroupMemoryBarrier(){}\n" +"void GroupMemoryBarrierWithGroupSync(){}\n" +"\n" +"#endif\n" +"\n" +"\n" +"// Type conversion functions\n" +"\n" +"vec4 _ExpandVector( float x ){ return vec4( x, x, x, x ); }\n" +"vec4 _ExpandVector( vec2 f2 ){ return vec4( f2.x, f2.y, 0.0, 1.0 ); }\n" +"vec4 _ExpandVector( vec3 f3 ){ return vec4( f3.x, f3.y, f3.z, 1.0 ); }\n" +"vec4 _ExpandVector( vec4 f4 ){ return vec4( f4.x, f4.y, f4.z, f4.w ); }\n" +"\n" +"ivec4 _ExpandVector( int x ){ return ivec4( x, x, x, x ); }\n" +"ivec4 _ExpandVector( ivec2 i2 ){ return ivec4( i2.x, i2.y, 0, 0 ); }\n" +"ivec4 _ExpandVector( ivec3 i3 ){ return ivec4( i3.x, i3.y, i3.z, 0 ); }\n" +"ivec4 _ExpandVector( ivec4 i4 ){ return ivec4( i4.x, i4.y, i4.z, i4.w ); }\n" +"\n" +"uvec4 _ExpandVector( uint x ){ return uvec4( x, x, x, x ); }\n" +"uvec4 _ExpandVector( uvec2 u2 ){ return uvec4( u2.x, u2.y, 0u, 0u ); }\n" +"uvec4 _ExpandVector( uvec3 u3 ){ return uvec4( u3.x, u3.y, u3.z, 0u ); }\n" +"uvec4 _ExpandVector( uvec4 u4 ){ return uvec4( u4.x, u4.y, u4.z, u4.w ); }\n" +"\n" +"bvec4 _ExpandVector( bool x ){ return bvec4( x, x, x, x ); }\n" +"bvec4 _ExpandVector( bvec2 b2 ){ return bvec4( b2.x, b2.y, false, false ); }\n" +"bvec4 _ExpandVector( bvec3 b3 ){ return bvec4( b3.x, b3.y, b3.z, false ); }\n" +"bvec4 _ExpandVector( bvec4 b4 ){ return bvec4( b4.x, b4.y, b4.z, b4.w ); }\n" +"\n" +"\n" +"void _TypeConvertStore( out float Dst, in int Src ){ Dst = float( Src ); }\n" +"void _TypeConvertStore( out float Dst, in uint Src ){ Dst = float( Src ); }\n" +"void _TypeConvertStore( out float Dst, in float Src ){ Dst = float( Src ); }\n" +"void _TypeConvertStore( out uint Dst, in int Src ){ Dst = uint( Src ); }\n" +"void _TypeConvertStore( out uint Dst, in uint Src ){ Dst = uint( Src ); }\n" +"void _TypeConvertStore( out uint Dst, in float Src ){ Dst = uint( Src ); }\n" +"void _TypeConvertStore( out int Dst, in int Src ){ Dst = int( Src ); }\n" +"void _TypeConvertStore( out int Dst, in uint Src ){ Dst = int( Src ); }\n" +"void _TypeConvertStore( out int Dst, in float Src ){ Dst = int( Src ); }\n" +"\n" +"int _ToInt( int x ) { return int(x); }\n" +"int _ToInt( uint x ) { return int(x); }\n" +"int _ToInt( float x ){ return int(x); }\n" +"int _ToInt( bool x ) { return x ? 1 : 0; }\n" +"\n" +"float _ToFloat( int x ) { return float(x); }\n" +"float _ToFloat( uint x ) { return float(x); }\n" +"float _ToFloat( float x ){ return float(x); }\n" +"float _ToFloat( bool x ) { return x ? 1.0 : 0.0;}\n" +"\n" +"uint _ToUint( int x ) { return uint(x); }\n" +"uint _ToUint( uint x ) { return uint(x); }\n" +"uint _ToUint( float x ){ return uint(x); }\n" +"uint _ToUint( bool x ) { return x ? 1u : 0u; }\n" +"\n" +"bool _ToBool( int x ) { return x != 0 ? true : false; }\n" +"bool _ToBool( uint x ) { return x != 0u ? true : false; }\n" +"bool _ToBool( float x ){ return x != 0.0 ? true : false; }\n" +"bool _ToBool( bool x ) { return x; }\n" +"\n" +"#define _ToVec2(x,y) vec2(_ToFloat(x), _ToFloat(y))\n" +"#define _ToVec3(x,y,z) vec3(_ToFloat(x), _ToFloat(y), _ToFloat(z))\n" +"#define _ToVec4(x,y,z,w) vec4(_ToFloat(x), _ToFloat(y), _ToFloat(z), _ToFloat(w))\n" +"\n" +"#define _ToIvec2(x,y) ivec2(_ToInt(x), _ToInt(y))\n" +"#define _ToIvec3(x,y,z) ivec3(_ToInt(x), _ToInt(y), _ToInt(z))\n" +"#define _ToIvec4(x,y,z,w) ivec4(_ToInt(x), _ToInt(y), _ToInt(z), _ToInt(w))\n" +"\n" +"#define _ToUvec2(x,y) uvec2(_ToUint(x), _ToUint(y))\n" +"#define _ToUvec3(x,y,z) uvec3(_ToUint(x), _ToUint(y), _ToUint(z))\n" +"#define _ToUvec4(x,y,z,w) uvec4(_ToUint(x), _ToUint(y), _ToUint(z), _ToUint(w))\n" +"\n" +"#define _ToBvec2(x,y) bvec2(_ToBool(x), _ToBool(y))\n" +"#define _ToBvec3(x,y,z) bvec3(_ToBool(x), _ToBool(y), _ToBool(z))\n" +"#define _ToBvec4(x,y,z,w) bvec4(_ToBool(x), _ToBool(y), _ToBool(z), _ToBool(w))\n" +"\n" +"\n" +"int _ToIvec( uint u1 ){ return _ToInt( u1 ); }\n" +"ivec2 _ToIvec( uvec2 u2 ){ return _ToIvec2( u2.x, u2.y ); }\n" +"ivec3 _ToIvec( uvec3 u3 ){ return _ToIvec3( u3.x, u3.y, u3.z ); }\n" +"ivec4 _ToIvec( uvec4 u4 ){ return _ToIvec4( u4.x, u4.y, u4.z, u4.w ); }\n" +"\n" +"int _ToIvec( int i1 ){ return i1; }\n" +"ivec2 _ToIvec( ivec2 i2 ){ return i2; }\n" +"ivec3 _ToIvec( ivec3 i3 ){ return i3; }\n" +"ivec4 _ToIvec( ivec4 i4 ){ return i4; }\n" +"\n" +"int _ToIvec( float f1 ){ return _ToInt( f1 ); }\n" +"ivec2 _ToIvec( vec2 f2 ){ return _ToIvec2( f2.x, f2.y ); }\n" +"ivec3 _ToIvec( vec3 f3 ){ return _ToIvec3( f3.x, f3.y, f3.z ); }\n" +"ivec4 _ToIvec( vec4 f4 ){ return _ToIvec4( f4.x, f4.y, f4.z, f4.w ); }\n" +"\n" +"\n" +"float _ToVec( uint u1 ){ return _ToFloat(u1); }\n" +"vec2 _ToVec( uvec2 u2 ){ return _ToVec2( u2.x, u2.y ); }\n" +"vec3 _ToVec( uvec3 u3 ){ return _ToVec3( u3.x, u3.y, u3.z ); }\n" +"vec4 _ToVec( uvec4 u4 ){ return _ToVec4( u4.x, u4.y, u4.z, u4.w ); }\n" +" \n" +"float _ToVec( int i1 ){ return _ToFloat(i1); }\n" +"vec2 _ToVec( ivec2 i2 ){ return _ToVec2( i2.x, i2.y ); }\n" +"vec3 _ToVec( ivec3 i3 ){ return _ToVec3( i3.x, i3.y, i3.z ); }\n" +"vec4 _ToVec( ivec4 i4 ){ return _ToVec4( i4.x, i4.y, i4.z, i4.w ); }\n" +" \n" +"float _ToVec( float f1 ){ return f1; }\n" +"vec2 _ToVec( vec2 f2 ){ return f2; }\n" +"vec3 _ToVec( vec3 f3 ){ return f3; }\n" +"vec4 _ToVec( vec4 f4 ){ return f4; }\n" +"\n" +"\n" +"uint _ToUvec( uint u1 ){ return u1; }\n" +"uvec2 _ToUvec( uvec2 u2 ){ return u2; }\n" +"uvec3 _ToUvec( uvec3 u3 ){ return u3; }\n" +"uvec4 _ToUvec( uvec4 u4 ){ return u4; }\n" +" \n" +"uint _ToUvec( int i1 ){ return _ToUint( i1 ); }\n" +"uvec2 _ToUvec( ivec2 i2 ){ return _ToUvec2( i2.x, i2.y ); }\n" +"uvec3 _ToUvec( ivec3 i3 ){ return _ToUvec3( i3.x, i3.y, i3.z ); }\n" +"uvec4 _ToUvec( ivec4 i4 ){ return _ToUvec4( i4.x, i4.y, i4.z, i4.w ); }\n" +" \n" +"uint _ToUvec( float f1 ){ return _ToUint( f1 ); }\n" +"uvec2 _ToUvec( vec2 f2 ){ return _ToUvec2( f2.x, f2.y ); }\n" +"uvec3 _ToUvec( vec3 f3 ){ return _ToUvec3( f3.x, f3.y, f3.z ); }\n" +"uvec4 _ToUvec( vec4 f4 ){ return _ToUvec4( f4.x, f4.y, f4.z, f4.w ); }\n" +"\n" +"\n" +"// TEXTURE FUNCTION STUB MACROS\n" +"// https://www.opengl.org/wiki/Sampler_(GLSL)\n" +"\n" +"\n" +"// Texture size queries\n" +"// https://www.opengl.org/sdk/docs/man/html/textureSize.xhtml\n" +"// textureSize returns the dimensions of level lod (if present) of the texture bound to sampler. \n" +"// The components in the return value are filled in, in order, with the width, height and depth \n" +"// of the texture. For the array forms, the last component of the return value is the number of \n" +"// layers in the texture array.\n" +"\n" +"//#if !(defined(DESKTOP_GL) && __VERSION__ >= 430)\n" +"# define textureQueryLevels(x) 0 // Only supported on 4.3+\n" +"//#endif\n" +"\n" +"#define GetTex1DDimensions_1(Sampler, Width)\\\n" +"{ \\\n" +" _TypeConvertStore( Width, textureSize(Sampler, 0) );\\\n" +"}\n" +"\n" +"#define GetTex1DDimensions_3(Sampler, MipLevel, Width, NumberOfMipLevels)\\\n" +"{ \\\n" +" _TypeConvertStore( Width, textureSize(Sampler, _ToInt(MipLevel)) ); \\\n" +" _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) ); \\\n" +"}\n" +"\n" +"#define GetTex1DArrDimensions_2(Sampler, Width, Elements)\\\n" +"{ \\\n" +" ivec2 i2Size = textureSize(Sampler, 0); \\\n" +" _TypeConvertStore( Width, i2Size.x );\\\n" +" _TypeConvertStore( Elements, i2Size.y );\\\n" +"}\n" +"\n" +"#define GetTex1DArrDimensions_4(Sampler, MipLevel, Width, Elements, NumberOfMipLevels)\\\n" +"{ \\\n" +" ivec2 i2Size = textureSize(Sampler, _ToInt(MipLevel)); \\\n" +" _TypeConvertStore( Width, i2Size.x ); \\\n" +" _TypeConvertStore( Elements, i2Size.y ); \\\n" +" _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\\\n" +"}\n" +"\n" +"#define GetTex2DDimensions_2(Sampler, Width, Height)\\\n" +"{ \\\n" +" ivec2 i2Size = textureSize(Sampler, 0); \\\n" +" _TypeConvertStore( Width, i2Size.x ); \\\n" +" _TypeConvertStore( Height, i2Size.y ); \\\n" +"}\n" +"\n" +"#define GetTex2DDimensions_4(Sampler, MipLevel, Width, Height, NumberOfMipLevels)\\\n" +"{ \\\n" +" ivec2 i2Size = textureSize(Sampler, _ToInt(MipLevel) ); \\\n" +" _TypeConvertStore( Width, i2Size.x ); \\\n" +" _TypeConvertStore( Height, i2Size.y ); \\\n" +" _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\\\n" +"}\n" +"\n" +"#define GetTex2DArrDimensions_3(Sampler, Width, Height, Elements)\\\n" +"{ \\\n" +" ivec3 i3Size = textureSize(Sampler, 0); \\\n" +" _TypeConvertStore( Width, i3Size.x ); \\\n" +" _TypeConvertStore( Height, i3Size.y ); \\\n" +" _TypeConvertStore( Elements,i3Size.z ); \\\n" +"}\n" +"\n" +"#define GetTex2DArrDimensions_5(Sampler, MipLevel, Width, Height, Elements, NumberOfMipLevels)\\\n" +"{ \\\n" +" ivec3 i3Size = textureSize(Sampler, _ToInt(MipLevel)); \\\n" +" _TypeConvertStore( Width, i3Size.x ); \\\n" +" _TypeConvertStore( Height, i3Size.y ); \\\n" +" _TypeConvertStore( Elements, i3Size.z ); \\\n" +" _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\\\n" +"}\n" +"\n" +"#define GetTex3DDimensions_3(Sampler, Width, Height, Depth)\\\n" +"{ \\\n" +" ivec3 i3Size = textureSize(Sampler, 0); \\\n" +" _TypeConvertStore( Width, i3Size.x ); \\\n" +" _TypeConvertStore( Height, i3Size.y ); \\\n" +" _TypeConvertStore( Depth, i3Size.z ); \\\n" +"}\n" +"\n" +"#define GetTex3DDimensions_5(Sampler, MipLevel, Width, Height, Depth, NumberOfMipLevels)\\\n" +"{ \\\n" +" ivec3 i3Size = textureSize(Sampler, _ToInt(MipLevel)); \\\n" +" _TypeConvertStore( Width, i3Size.x ); \\\n" +" _TypeConvertStore( Height, i3Size.y ); \\\n" +" _TypeConvertStore( Depth, i3Size.z ); \\\n" +" _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\\\n" +"}\n" +"\n" +"#define GetTex2DMSDimensions_3(Sampler, Width, Height, NumberOfSamples)\\\n" +"{ \\\n" +" ivec2 i2Size = textureSize(Sampler); \\\n" +" _TypeConvertStore( Width, i2Size.x ); \\\n" +" _TypeConvertStore( Height, i2Size.y ); \\\n" +" _TypeConvertStore( NumberOfSamples, 0 );\\\n" +"}\n" +"\n" +"#define GetTex2DMSArrDimensions_4(Sampler, Width, Height, Elements, NumberOfSamples)\\\n" +"{ \\\n" +" ivec3 i3Size = textureSize(Sampler); \\\n" +" _TypeConvertStore( Width, i3Size.x );\\\n" +" _TypeConvertStore( Height, i3Size.y );\\\n" +" _TypeConvertStore( Elements, i3Size.z );\\\n" +" _TypeConvertStore( NumberOfSamples, 0 );\\\n" +"}\n" +"\n" +"\n" +"// https://www.opengl.org/sdk/docs/man/html/imageSize.xhtml\n" +"// imageSize returns the dimensions of the image bound to image. The components in the \n" +"// return value are filled in, in order, with the width, height and depth of the image. \n" +"// For the array forms, the last component of the return value is the number of layers \n" +"// in the texture array.\n" +"\n" +"#define GetRWTex1DDimensions_1(Tex, Width)\\\n" +"{ \\\n" +" _TypeConvertStore( Width, imageSize(Tex) ); \\\n" +"}\n" +"\n" +"#define GetRWTex1DArrDimensions_2(Tex, Width, Elements)\\\n" +"{ \\\n" +" ivec2 i2Size = imageSize(Tex); \\\n" +" _TypeConvertStore( Width, i2Size.x ); \\\n" +" _TypeConvertStore( Elements, i2Size.y ); \\\n" +"}\n" +"\n" +"#define GetRWTex2DDimensions_2(Tex, Width, Height)\\\n" +"{ \\\n" +" ivec2 i2Size = imageSize(Tex); \\\n" +" _TypeConvertStore( Width, i2Size.x ); \\\n" +" _TypeConvertStore( Height, i2Size.y ); \\\n" +"}\n" +"\n" +"#define GetRWTex2DArrDimensions_3(Tex, Width, Height, Elements)\\\n" +"{ \\\n" +" ivec3 i3Size = imageSize(Tex); \\\n" +" _TypeConvertStore( Width, i3Size.x );\\\n" +" _TypeConvertStore( Height, i3Size.y );\\\n" +" _TypeConvertStore( Elements, i3Size.z );\\\n" +"}\n" +"\n" +"#define GetRWTex3DDimensions_3(Tex, Width, Height, Depth)\\\n" +"{ \\\n" +" ivec3 i3Size = imageSize(Tex); \\\n" +" _TypeConvertStore( Width, i3Size.x ); \\\n" +" _TypeConvertStore( Height, i3Size.y ); \\\n" +" _TypeConvertStore( Depth, i3Size.z ); \\\n" +"}\n" +"\n" +"\n" +"\n" +"// Texture sampling operations\n" +"\n" +"\n" +"// IMPORTANT NOTE ABOUT OFFSET\n" +"// Offset parameter to all texture sampling functions must be a constant expression.\n" +"// If it is not, the shader will be successfully compiled, HOWEVER the value of Offset \n" +"// will silently be zero. \n" +"//\n" +"// A constant expression in GLSL is defined as follows:\n" +"// * A literal value.\n" +"// * A const-qualified variable with an explicit initializer (so not a function parameter).\n" +"// * The result of the length() function of an array, but only if the array has an explicit size.\n" +"// * The result of most operators, so long as all the operands are themselves constant expressions. \n" +"// The operators not on this list are any assignment operators (+= and so forth), and the comma operator.\n" +"// * The result of a constructor for a type, but only if all of the arguments to the constructor are \n" +"// themselves constant expressions.\n" +"// * The return value of any built-in function, but only if all of the arguments to the function are \n" +"// themselves constant expressions. Opaque Types are never constant expressions. Note that the \n" +"// functions dFdx, dFdy, and fwidth will return 0, when used in a context that requires a constant \n" +"// expression (such as a const variable initializer).\n" +"// \n" +"// The list above does not include return value of a function, even when the value is compile-time expression.\n" +"// As a result, we cannot use type conversion functions for Offset parameter.\n" +"\n" +"// In all texture sampling functions, the last component of Coords is used as Dsub and the array layer is specified \n" +"// in the second to last component of Coords. (The second component of Coords is unused for 1D shadow lookups.)\n" +"// For cube array textures, Dsub is specified as a separate parameter\n" +"// mip\n" +"#define SampleCmpLevel0Tex1D_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, 0.0, CompareValue), 0.0)\n" +"#define SampleCmpLevel0Tex1DArr_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0)\n" +"#define SampleCmpLevel0Tex2D_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0)\n" +"#define SampleCmpLevel0Tex2DArr_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for sampler2DArrayShadow\n" +"#define SampleCmpLevel0TexCube_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for samplerCubeShadow\n" +"#define SampleCmpLevel0TexCubeArr_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for samplerCubeArrayShadow\n" +"\n" +"// mip\n" +"#define SampleCmpLevel0Tex1D_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, 0.0, CompareValue), 0.0, int(Offset))\n" +"#define SampleCmpLevel0Tex1DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0, int(Offset))\n" +"#define SampleCmpLevel0Tex2D_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0, ivec2((Offset).xy))\n" +"#define SampleCmpLevel0Tex2DArr_4(Tex, Sampler, Coords, CompareValue, Offset) 0.0 // No textureLodOffset for sampler2DArrayShadow\n" +"\n" +"\n" +"// https://www.opengl.org/sdk/docs/man/html/texture.xhtml - note: there are many mistakes on the page\n" +"#ifdef FRAGMENT_SHADER\n" +"\n" +"# define Sample_2(Tex, Sampler, Coords) texture (Tex, _ToVec(Coords))\n" +"# define Sample_3(Tex, Sampler, Coords, Offset) textureOffset(Tex, _ToVec(Coords), Offset)\n" +"# define SampleBias_3(Tex, Sampler, Coords, Bias) texture (Tex, _ToVec(Coords), _ToFloat(Bias))\n" +"# define SampleBias_4(Tex, Sampler, Coords, Bias, Offset) textureOffset(Tex, _ToVec(Coords), Offset, _ToFloat(Bias))\n" +"\n" +"# define SampleCmpTex1D_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, 0.0, CompareValue))\n" +"# define SampleCmpTex1DArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue))\n" +"# define SampleCmpTex2D_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue))\n" +"# define SampleCmpTex2DArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue))\n" +"# define SampleCmpTexCube_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue))\n" +"# define SampleCmpTexCubeArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, (Coords).w), _ToFloat(CompareValue))\n" +"\n" +"# define SampleCmpTex1D_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, 0.0, CompareValue), int(Offset))\n" +"# define SampleCmpTex1DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), int(Offset))\n" +"# define SampleCmpTex2D_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), ivec2((Offset).xy))\n" +"# define SampleCmpTex2DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue), ivec2((Offset).xy))\n" +"\n" +"#else\n" +"\n" +"// Derivatives are only available in fragment shader. GLSL compiler fails when it\n" +"// encounters texture() or textureOffset() instructions in other types of shaders. So\n" +"// to let the shader be compiled and to have something meaningful, replace such operations\n" +"// with textureLod() and textureLodOffset()\n" +"\n" +"# define Sample_2(Tex, Sampler, Coords) textureLod (Tex, _ToVec(Coords), 0.0)\n" +"# define Sample_3(Tex, Sampler, Coords, Offset) textureLodOffset(Tex, _ToVec(Coords), 0.0, Offset)\n" +"# define SampleBias_3(Tex, Sampler, Coords, Bias) textureLod (Tex, _ToVec(Coords), 0.0 + _ToFloat(Bias))\n" +"# define SampleBias_4(Tex, Sampler, Coords, Bias, Offset) textureLodOffset(Tex, _ToVec(Coords), 0.0 + _ToFloat(Bias), Offset)\n" +"\n" +"# define SampleCmpTex1D_3 SampleCmpLevel0Tex1D_3\n" +"# define SampleCmpTex1DArr_3 SampleCmpLevel0Tex1DArr_3\n" +"# define SampleCmpTex2D_3 SampleCmpLevel0Tex2D_3\n" +"# define SampleCmpTex2DArr_3 SampleCmpLevel0Tex2DArr_3\n" +"# define SampleCmpTexCube_3 SampleCmpLevel0TexCube_3\n" +"# define SampleCmpTexCubeArr_3 SampleCmpLevel0TexCubeArr_3\n" +" \n" +"# define SampleCmpTex1D_4 SampleCmpLevel0Tex1D_4\n" +"# define SampleCmpTex1DArr_4 SampleCmpLevel0Tex1DArr_4\n" +"# define SampleCmpTex2D_4 SampleCmpLevel0Tex2D_4\n" +"# define SampleCmpTex2DArr_4 SampleCmpLevel0Tex2DArr_4\n" +"\n" +"#endif\n" +"\n" +"// https://www.opengl.org/sdk/docs/man/html/textureLod.xhtml\n" +"#define SampleLevel_3(Tex, Sampler, Coords, Level) textureLod (Tex, _ToVec(Coords), _ToFloat(Level))\n" +"#define SampleLevel_4(Tex, Sampler, Coords, Level, Offset) textureLodOffset(Tex, _ToVec(Coords), _ToFloat(Level), Offset)\n" +"\n" +"// https://www.opengl.org/sdk/docs/man/html/textureGrad.xhtml\n" +"#define SampleGrad_4(Tex, Sampler, Coords, DDX, DDY) textureGrad (Tex, _ToVec(Coords), _ToVec(DDX), _ToVec(DDY))\n" +"#define SampleGrad_5(Tex, Sampler, Coords, DDX, DDY, Offset) textureGradOffset(Tex, _ToVec(Coords), _ToVec(DDX), _ToVec(DDY), Offset)\n" +"\n" +"\n" +"// texelFetch performs a lookup of a single texel from texture coordinate P in the texture \n" +"// bound to sampler. The array layer is specified in the last component of P for array forms. \n" +"// The lod parameter (if present) specifies the level-of-detail from which the texel will be fetched. \n" +"// The sample specifies which sample within the texel will be returned when reading from a multi-sample texure.\n" +"\n" +"#define LoadTex1D_1(Tex, Location) texelFetch (Tex, _ToInt((Location).x), _ToInt((Location).y))\n" +"#define LoadTex1D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToInt((Location).x), _ToInt((Location).y), int(Offset))\n" +"#define LoadTex1DArr_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xy), _ToInt((Location).z) )\n" +"#define LoadTex1DArr_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xy), _ToInt((Location).z), int(Offset))\n" +"#define LoadTex2D_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xy), _ToInt((Location).z))\n" +"#define LoadTex2D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xy), _ToInt((Location).z), ivec2( (Offset).xy) )\n" +"#define LoadTex2DArr_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xyz), _ToInt((Location).w) )\n" +"#define LoadTex2DArr_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xyz), _ToInt((Location).w), ivec2( (Offset).xy))\n" +"#define LoadTex3D_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xyz), _ToInt((Location).w))\n" +"#define LoadTex3D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xyz), _ToInt((Location).w), ivec3( (Offset).xyz))\n" +"#define LoadTex2DMS_2(Tex, Location, Sample) texelFetch(Tex, _ToIvec( (Location).xy), _ToInt(Sample))\n" +"#define LoadTex2DMS_3(Tex, Location, Sample, Offset)texelFetch(Tex, _ToIvec2( (Location).x + (Offset).x, (Location).y + (Offset).y), int(Sample) ) // No texelFetchOffset for texture2DMS\n" +"#define LoadTex2DMSArr_2(Tex, Location, Sample) texelFetch(Tex, _ToIvec( (Location).xyz), _ToInt(Sample))\n" +"#define LoadTex2DMSArr_3(Tex, Location, Sample, Offset)texelFetch(Tex, _ToIvec3( (Location).x + (Offset).x, (Location).y + (Offset).y, (Location).z), int(Sample)) // No texelFetchOffset for texture2DMSArray\n" +"\n" +"//https://www.opengl.org/sdk/docs/man/html/imageLoad.xhtml\n" +"#define LoadRWTex1D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).x) )\n" +"#define LoadRWTex1DArr_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xy) )\n" +"#define LoadRWTex2D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xy) )\n" +"#define LoadRWTex2DArr_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xyz) )\n" +"#define LoadRWTex3D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xyz) )\n" +"\n" +"\n" +"#define Gather_2(Tex, Sampler, Location) textureGather (Tex, _ToVec(Location))\n" +"#define Gather_3(Tex, Sampler, Location, Offset)textureGatherOffset(Tex, _ToVec(Location), Offset)\n" +"\n" +"#define GatherCmp_3(Tex, Sampler, Location, CompareVal) textureGather (Tex, _ToVec(Location), _ToFloat(CompareVal))\n" +"#define GatherCmp_4(Tex, Sampler, Location, CompareVal, Offset)textureGatherOffset(Tex, _ToVec(Location), _ToFloat(CompareVal), Offset)\n" +"\n" +"// Atomic operations\n" +"#define InterlockedAddSharedVar_2(dest, value) atomicAdd(dest, value)\n" +"#define InterlockedAddSharedVar_3(dest, value, orig_val) orig_val = atomicAdd(dest, value)\n" +"#define InterlockedAddImage_2(img, coords, value) imageAtomicAdd(img, _ToIvec(coords), value)\n" +"#define InterlockedAddImage_3(img, coords, value, orig_val)orig_val = imageAtomicAdd(img, _ToIvec(coords), value)\n" +"\n" +"#define InterlockedAndSharedVar_2(dest, value) atomicAnd(dest, value)\n" +"#define InterlockedAndSharedVar_3(dest, value, orig_val) orig_val = atomicAnd(dest, value)\n" +"#define InterlockedAndImage_2(img, coords, value) imageAtomicAnd(img, _ToIvec(coords), value)\n" +"#define InterlockedAndImage_3(img, coords, value, orig_val)orig_val = imageAtomicAnd(img, _ToIvec(coords), value)\n" +"\n" +"#define InterlockedMaxSharedVar_2(dest, value) atomicMax(dest, value)\n" +"#define InterlockedMaxSharedVar_3(dest, value, orig_val) orig_val = atomicMax(dest, value)\n" +"#define InterlockedMaxImage_2(img, coords, value) imageAtomicMax(img, _ToIvec(coords), value)\n" +"#define InterlockedMaxImage_3(img, coords, value, orig_val)orig_val = imageAtomicMax(img, _ToIvec(coords), value)\n" +"\n" +"#define InterlockedMinSharedVar_2(dest, value) atomicMin(dest, value)\n" +"#define InterlockedMinSharedVar_3(dest, value, orig_val) orig_val = atomicMin(dest, value)\n" +"#define InterlockedMinImage_2(img, coords, value) imageAtomicMin(img, _ToIvec(coords), value)\n" +"#define InterlockedMinImage_3(img, coords, value, orig_val)orig_val = imageAtomicMin(img, _ToIvec(coords), value)\n" +"\n" +"#define InterlockedOrSharedVar_2(dest, value) atomicOr(dest, value)\n" +"#define InterlockedOrSharedVar_3(dest, value, orig_val) orig_val = atomicOr(dest, value)\n" +"#define InterlockedOrImage_2(img, coords, value) imageAtomicOr(img, _ToIvec(coords), value)\n" +"#define InterlockedOrImage_3(img, coords, value, orig_val)orig_val = imageAtomicOr(img, _ToIvec(coords), value)\n" +"\n" +"#define InterlockedXorSharedVar_2(dest, value) atomicXor(dest, value)\n" +"#define InterlockedXorSharedVar_3(dest, value, orig_val) orig_val = atomicXor(dest, value)\n" +"#define InterlockedXorImage_2(img, coords, value) imageAtomicXor(img, _ToIvec(coords), value)\n" +"#define InterlockedXorImage_3(img, coords, value, orig_val)orig_val = imageAtomicXor(img, _ToIvec(coords), value)\n" +"\n" +"// There is actually no InterlockedExchange() with 2 arguments\n" +"#define InterlockedExchangeSharedVar_2(dest, value) atomicExchange(dest, value)\n" +"#define InterlockedExchangeSharedVar_3(dest, value, orig_val) orig_val = atomicExchange(dest, value)\n" +"#define InterlockedExchangeImage_2(img, coords, value) imageAtomicExchange(img, _ToIvec(coords), value)\n" +"#define InterlockedExchangeImage_3(img, coords, value, orig_val)orig_val = imageAtomicExchange(img, _ToIvec(coords), value)\n" +"\n" +"//uint imageAtomicCompSwap( image img, IVec P, nint compare, nint data);\n" +"//void InterlockedCompareExchange( in R dest, in T compare_value, in T value, out T original_value);\n" +"#define InterlockedCompareExchangeSharedVar_4(dest, cmp_val, value, orig_val) orig_val = atomicCompSwap(dest, cmp_val, value)\n" +"#define InterlockedCompareExchangeImage_4(img, coords, cmp_val, value, orig_val) orig_val = imageAtomicCompSwap(img, _ToIvec(coords), cmp_val, value)\n" +"\n" +"#define InterlockedCompareStoreSharedVar_3(dest, cmp_val, value) atomicCompSwap(dest, cmp_val, value)\n" +"#define InterlockedCompareStoreImage_3(img, coords, cmp_val, value)imageAtomicCompSwap(img, _ToIvec(coords), cmp_val, value)\n" +"\n" +"\n" +"// Swizzling macros\n" +"#define _SWIZZLE0\n" +"#define _SWIZZLE1 .x\n" +"#define _SWIZZLE2 .xy\n" +"#define _SWIZZLE3 .xyz\n" +"#define _SWIZZLE4 .xyzw\n" +"\n" +"// Helper functions\n" +"\n" +"float2 NormalizedDeviceXYToTexUV( float2 f2ProjSpaceXY )\n" +"{\n" +" return float2(0.5,0.5) + float2(0.5,0.5) * f2ProjSpaceXY.xy;\n" +"}\n" +"\n" +"float NormalizedDeviceZToDepth(float fNDC_Z)\n" +"{\n" +" return fNDC_Z * 0.5 + 0.5; // [-1, +1] -> [0, 1]\n" +"}\n" +"\n" +"float DepthToNormalizedDeviceZ(float fDepth)\n" +"{\n" +" return fDepth * 2.0 - 1.0; // [0, 1] -> [-1, +1]\n" +"}\n" +"\n" +"#define F3NDC_XYZ_TO_UVD_SCALE float3(0.5, 0.5, 0.5)\n" +"\n" +"#define NDC_MIN_Z -1.0 // Minimal z in the normalized device space\n" +"\n" +"#define MATRIX_ELEMENT(mat, row, col) mat[col][row]\n" +"\n" +"#endif // _GLSL_DEFINITIONS_\n" diff --git a/Graphics/GraphicsEngineOpenGL/include/GLStubs.h b/Graphics/GraphicsEngineOpenGL/include/GLStubs.h new file mode 100644 index 00000000..f5308af8 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLStubs.h @@ -0,0 +1,1051 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +// Define unsupported formats for OpenGL ES +#ifndef GL_RGBA16 +# define GL_RGBA16 0x805B +#endif + +#ifndef GL_RGBA16_SNORM +# define GL_RGBA16_SNORM 0x8F9B +#endif + +#ifndef GL_RG16 +# define GL_RG16 0x822C +#endif + +#ifndef GL_RG16_SNORM +# define GL_RG16_SNORM 0x8F99 +#endif + +#ifndef GL_R16 +# define GL_R16 0x822A +#endif + +#ifndef GL_R16_SNORM +# define GL_R16_SNORM 0x8F98 +#endif + +#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT +# define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#endif + +#ifndef GL_COMPRESSED_SRGB_S3TC_DXT1_EXT +# define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#endif + +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT +# define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#endif + +#ifndef GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT +# define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#endif + +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT +# define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT +# define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif + +#ifndef GL_COMPRESSED_RED_RGTC1 +# define GL_COMPRESSED_RED_RGTC1 0x8DBB +#endif + +#ifndef GL_COMPRESSED_SIGNED_RED_RGTC1 +# define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#endif + +#ifndef GL_COMPRESSED_RG_RGTC2 +# define GL_COMPRESSED_RG_RGTC2 0x8DBD +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG_RGTC2 +# define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT +# define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT +# define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#endif + +#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM +# define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#endif + +#ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM +# define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#endif + +#ifndef GL_UNSIGNED_SHORT_5_6_5_REV +# define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#endif + +#ifndef GL_UNSIGNED_INT_10_10_10_2 +# define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#endif + +#ifndef GL_UNSIGNED_SHORT_5_6_5_REV +# define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#endif + +#ifndef GL_UNSIGNED_SHORT_1_5_5_5_REV +# define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#endif + +// Define unsupported shaders +#ifndef GL_GEOMETRY_SHADER +# define GL_GEOMETRY_SHADER 0x8DD9 +#endif + +#ifndef GL_TESS_CONTROL_SHADER +# define GL_TESS_CONTROL_SHADER 0x8E88 +#endif + +#ifndef GL_TESS_EVALUATION_SHADER +# define GL_TESS_EVALUATION_SHADER 0x8E87 +#endif + +// Define unsupported texture filtering modes +#ifndef GL_CLAMP_TO_BORDER +# define GL_CLAMP_TO_BORDER 0 +#endif + +#ifndef GL_MIRROR_CLAMP_TO_EDGE +# define GL_MIRROR_CLAMP_TO_EDGE 0 +#endif + +// Define unsupported bind points +#ifndef GL_DRAW_INDIRECT_BUFFER +# define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#endif + +#ifndef GL_DISPATCH_INDIRECT_BUFFER +# define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#endif + +#ifndef GL_TEXTURE_1D_ARRAY +# define GL_TEXTURE_1D_ARRAY 0x8C18 +#endif + +#ifndef GL_TEXTURE_BINDING_1D_ARRAY +# define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#endif + +#ifndef GL_TEXTURE_1D +# define GL_TEXTURE_1D 0x0DE0 +#endif + +#ifndef GL_TEXTURE_BINDING_1D +# define GL_TEXTURE_BINDING_1D 0x8068 +#endif + +#ifndef GL_TEXTURE_2D_MULTISAMPLE +# define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#endif + +#ifndef GL_TEXTURE_BINDING_2D_MULTISAMPLE +# define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#endif + +#ifndef GL_TEXTURE_2D_MULTISAMPLE_ARRAY +# define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#endif + +#ifndef GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY +# define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#endif + +#ifndef GL_TEXTURE_BUFFER +# define GL_TEXTURE_BUFFER 0x8C2A +#endif + +// Define unsupported pipeline bind flags +#ifndef GL_VERTEX_SHADER_BIT +# define GL_VERTEX_SHADER_BIT 0x00000001 +#endif + +#ifndef GL_FRAGMENT_SHADER_BIT +# define GL_FRAGMENT_SHADER_BIT 0x00000002 +#endif + +#ifndef GL_GEOMETRY_SHADER_BIT +# define GL_GEOMETRY_SHADER_BIT 0x00000004 +#endif + +#ifndef GL_TESS_CONTROL_SHADER_BIT +# define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#endif + +#ifndef GL_TESS_EVALUATION_SHADER_BIT +# define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#endif + +#ifndef GL_COMPUTE_SHADER_BIT +# define GL_COMPUTE_SHADER_BIT 0x00000020 +#endif + +// Define unsupported sampler attributes +#ifndef GL_TEXTURE_LOD_BIAS +# define GL_TEXTURE_LOD_BIAS 0 +#endif + +#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT +# define GL_TEXTURE_MAX_ANISOTROPY_EXT 0 +#endif + +#ifndef GL_TEXTURE_BORDER_COLOR +# define GL_TEXTURE_BORDER_COLOR 0 +#endif + +// Other unsupported attributes +#ifndef GL_PROGRAM_SEPARABLE +# define GL_PROGRAM_SEPARABLE 0x8258 +#endif + +// Define unsupported uniform data types +#ifndef GL_SAMPLER_1D + #define GL_SAMPLER_1D 0x8B5D +#endif + +#ifndef GL_SAMPLER_1D_SHADOW + #define GL_SAMPLER_1D_SHADOW 0x8B61 +#endif + +#ifndef GL_SAMPLER_1D_ARRAY + #define GL_SAMPLER_1D_ARRAY 0x8DC0 +#endif + +#ifndef GL_SAMPLER_1D_ARRAY_SHADOW + #define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#endif + +#ifndef GL_INT_SAMPLER_1D + #define GL_INT_SAMPLER_1D 0x8DC9 +#endif + +#ifndef GL_INT_SAMPLER_1D_ARRAY + #define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#endif + +#ifndef GL_UNSIGNED_INT_SAMPLER_1D + #define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#endif + +#ifndef GL_UNSIGNED_INT_SAMPLER_1D_ARRAY + #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#endif + +#ifndef GL_SAMPLER_CUBE_MAP_ARRAY + #define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#endif + +#ifndef GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW + #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#endif + +#ifndef GL_INT_SAMPLER_CUBE_MAP_ARRAY + #define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#endif + +#ifndef GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY + #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#endif + +#ifndef GL_SAMPLER_BUFFER + #define GL_SAMPLER_BUFFER 0x8DC2 +#endif + +#ifndef GL_INT_SAMPLER_BUFFER + #define GL_INT_SAMPLER_BUFFER 0x8DD0 +#endif + +#ifndef GL_UNSIGNED_INT_SAMPLER_BUFFER + #define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#endif + +#ifndef GL_SAMPLER_2D_MULTISAMPLE + #define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#endif + +#ifndef GL_INT_SAMPLER_2D_MULTISAMPLE + #define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#endif + +#ifndef GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE + #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#endif + +#ifndef GL_SAMPLER_2D_MULTISAMPLE_ARRAY + #define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#endif + +#ifndef GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY + #define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#endif + +#ifndef GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY + #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#endif + + +#ifndef GL_IMAGE_1D + #define GL_IMAGE_1D 0x904C +#endif + +#ifndef GL_IMAGE_2D + #define GL_IMAGE_2D 0x904D +#endif + +#ifndef GL_IMAGE_3D + #define GL_IMAGE_3D 0x904E +#endif + +#ifndef GL_IMAGE_2D_RECT + #define GL_IMAGE_2D_RECT 0x904F +#endif + +#ifndef GL_IMAGE_CUBE + #define GL_IMAGE_CUBE 0x9050 +#endif + +#ifndef GL_IMAGE_BUFFER + #define GL_IMAGE_BUFFER 0x9051 +#endif + +#ifndef GL_IMAGE_1D_ARRAY + #define GL_IMAGE_1D_ARRAY 0x9052 +#endif + +#ifndef GL_IMAGE_2D_ARRAY + #define GL_IMAGE_2D_ARRAY 0x9053 +#endif + +#ifndef GL_IMAGE_CUBE_MAP_ARRAY + #define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#endif + +#ifndef GL_IMAGE_2D_MULTISAMPLE + #define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#endif + +#ifndef GL_IMAGE_2D_MULTISAMPLE_ARRAY + #define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#endif + +#ifndef GL_INT_IMAGE_1D + #define GL_INT_IMAGE_1D 0x9057 +#endif + +#ifndef GL_INT_IMAGE_2D + #define GL_INT_IMAGE_2D 0x9058 +#endif + +#ifndef GL_INT_IMAGE_3D + #define GL_INT_IMAGE_3D 0x9059 +#endif + +#ifndef GL_INT_IMAGE_2D_RECT + #define GL_INT_IMAGE_2D_RECT 0x905A +#endif + +#ifndef GL_INT_IMAGE_CUBE + #define GL_INT_IMAGE_CUBE 0x905B +#endif + +#ifndef GL_INT_IMAGE_BUFFER + #define GL_INT_IMAGE_BUFFER 0x905C +#endif + +#ifndef GL_INT_IMAGE_1D_ARRAY + #define GL_INT_IMAGE_1D_ARRAY 0x905D +#endif + +#ifndef GL_INT_IMAGE_2D_ARRAY + #define GL_INT_IMAGE_2D_ARRAY 0x905E +#endif + +#ifndef GL_INT_IMAGE_CUBE_MAP_ARRAY + #define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#endif + +#ifndef GL_INT_IMAGE_2D_MULTISAMPLE + #define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#endif + +#ifndef GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY + #define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_1D + #define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D + #define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_3D + #define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D_RECT + #define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_CUBE + #define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_BUFFER + #define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_1D_ARRAY + #define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D_ARRAY + #define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY + #define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE + #define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY + #define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#endif + + +// Compute shader stubs +#ifndef GL_READ_ONLY +# define GL_READ_ONLY 0x88B8 +#endif + +#ifndef GL_WRITE_ONLY +# define GL_WRITE_ONLY 0x88B9 +#endif + +#ifndef GL_READ_WRITE +# define GL_READ_WRITE 0x88BA +#endif + +#ifndef GL_COMPUTE_SHADER +# define GL_COMPUTE_SHADER 0x91B9 +#endif + +#ifndef glBindImageTexture + #define LOAD_GL_BIND_IMAGE_TEXTURE + typedef void (* PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); + extern PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; +#endif + +#ifndef glDispatchCompute + #define LOAD_GL_DISPATCH_COMPUTE + typedef void (* PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute; +#endif + +#ifndef glMemoryBarrier + #define LOAD_GL_MEMORY_BARRIER + typedef void (* PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); + extern PFNGLMEMORYBARRIERPROC glMemoryBarrier; +#endif + +#ifndef GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT +# define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#endif +#ifndef GL_ELEMENT_ARRAY_BARRIER_BIT +# define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#endif +#ifndef GL_UNIFORM_BARRIER_BIT +# define GL_UNIFORM_BARRIER_BIT 0x00000004 +#endif +#ifndef GL_TEXTURE_FETCH_BARRIER_BIT +# define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#endif +#ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT +# define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#endif +#ifndef GL_COMMAND_BARRIER_BIT +# define GL_COMMAND_BARRIER_BIT 0x00000040 +#endif +#ifndef GL_PIXEL_BUFFER_BARRIER_BIT +# define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#endif +#ifndef GL_TEXTURE_UPDATE_BARRIER_BIT +# define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#endif +#ifndef GL_BUFFER_UPDATE_BARRIER_BIT +# define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#endif +#ifndef GL_FRAMEBUFFER_BARRIER_BIT +# define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#endif +#ifndef GL_TRANSFORM_FEEDBACK_BARRIER_BIT +# define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#endif +#ifndef GL_ATOMIC_COUNTER_BARRIER_BIT +# define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#endif +#ifndef GL_SHADER_STORAGE_BARRIER_BIT +# define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#endif +#ifndef GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT +# define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#endif +#ifndef GL_QUERY_BUFFER_BARRIER_BIT +# define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#endif +#ifndef GL_ALL_BARRIER_BITS +# define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#endif + + + +//------------------------ Program interface query ------------------------ +#ifndef GL_UNIFORM +# define GL_UNIFORM 0x92E1 +#endif + +#ifndef GL_UNIFORM_BLOCK +# define GL_UNIFORM_BLOCK 0x92E2 +#endif + +#ifndef GL_PROGRAM_INPUT +# define GL_PROGRAM_INPUT 0x92E3 +#endif + +#ifndef GL_PROGRAM_OUTPUT +# define GL_PROGRAM_OUTPUT 0x92E4 +#endif + +#ifndef GL_BUFFER_VARIABLE +# define GL_BUFFER_VARIABLE 0x92E5 +#endif + +#ifndef GL_SHADER_STORAGE_BLOCK +# define GL_SHADER_STORAGE_BLOCK 0x92E6 +#endif + +#ifndef GL_IS_PER_PATCH +# define GL_IS_PER_PATCH 0x92E7 +#endif + +#ifndef GL_VERTEX_SUBROUTINE +# define GL_VERTEX_SUBROUTINE 0x92E8 +#endif + +#ifndef GL_TESS_CONTROL_SUBROUTINE +# define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#endif + +#ifndef GL_TESS_EVALUATION_SUBROUTINE +# define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#endif + +#ifndef GL_GEOMETRY_SUBROUTINE +# define GL_GEOMETRY_SUBROUTINE 0x92EB +#endif + +#ifndef GL_FRAGMENT_SUBROUTINE +# define GL_FRAGMENT_SUBROUTINE 0x92EC +#endif + +#ifndef GL_COMPUTE_SUBROUTINE +# define GL_COMPUTE_SUBROUTINE 0x92ED +#endif + +#ifndef GL_VERTEX_SUBROUTINE_UNIFORM +# define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#endif + +#ifndef GL_TESS_CONTROL_SUBROUTINE_UNIFORM +# define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#endif + +#ifndef GL_TESS_EVALUATION_SUBROUTINE_UNIFORM +# define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#endif + +#ifndef GL_GEOMETRY_SUBROUTINE_UNIFORM +# define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#endif + +#ifndef GL_FRAGMENT_SUBROUTINE_UNIFORM +# define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#endif + +#ifndef GL_COMPUTE_SUBROUTINE_UNIFORM +# define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#endif + +#ifndef GL_TRANSFORM_FEEDBACK_VARYING +# define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#endif + +#ifndef GL_ACTIVE_RESOURCES +# define GL_ACTIVE_RESOURCES 0x92F5 +#endif + +#ifndef GL_MAX_NAME_LENGTH +# define GL_MAX_NAME_LENGTH 0x92F6 +#endif + +#ifndef GL_MAX_NUM_ACTIVE_VARIABLES +# define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#endif + +#ifndef GL_MAX_NUM_COMPATIBLE_SUBROUTINES +# define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#endif + +#ifndef GL_NAME_LENGTH +# define GL_NAME_LENGTH 0x92F9 +#endif + +#ifndef GL_TYPE +# define GL_TYPE 0x92FA +#endif + +#ifndef GL_ARRAY_SIZE +# define GL_ARRAY_SIZE 0x92FB +#endif + +#ifndef GL_OFFSET +# define GL_OFFSET 0x92FC +#endif + +#ifndef GL_BLOCK_INDEX +# define GL_BLOCK_INDEX 0x92FD +#endif + +#ifndef GL_ARRAY_STRIDE +# define GL_ARRAY_STRIDE 0x92FE +#endif + +#ifndef GL_MATRIX_STRIDE +# define GL_MATRIX_STRIDE 0x92FF +#endif + +#ifndef GL_IS_ROW_MAJOR +# define GL_IS_ROW_MAJOR 0x9300 +#endif + +#ifndef GL_ATOMIC_COUNTER_BUFFER_INDEX +# define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#endif + +#ifndef GL_BUFFER_BINDING +# define GL_BUFFER_BINDING 0x9302 +#endif + +#ifndef GL_BUFFER_DATA_SIZE +# define GL_BUFFER_DATA_SIZE 0x9303 +#endif + +#ifndef GL_NUM_ACTIVE_VARIABLES +# define GL_NUM_ACTIVE_VARIABLES 0x9304 +#endif + +#ifndef GL_ACTIVE_VARIABLES +# define GL_ACTIVE_VARIABLES 0x9305 +#endif + +#ifndef GL_REFERENCED_BY_VERTEX_SHADER +# define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#endif + +#ifndef GL_REFERENCED_BY_TESS_CONTROL_SHADER +# define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#endif + +#ifndef GL_REFERENCED_BY_TESS_EVALUATION_SHADER +# define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#endif + +#ifndef GL_REFERENCED_BY_GEOMETRY_SHADER +# define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#endif + +#ifndef GL_REFERENCED_BY_FRAGMENT_SHADER +# define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#endif + +#ifndef GL_REFERENCED_BY_COMPUTE_SHADER +# define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#endif + +#ifndef GL_TOP_LEVEL_ARRAY_SIZE +# define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#endif + +#ifndef GL_TOP_LEVEL_ARRAY_STRIDE +# define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#endif + +#ifndef GL_LOCATION +# define GL_LOCATION 0x930E +#endif + +#ifndef GL_LOCATION_INDEX +# define GL_LOCATION_INDEX 0x930F +#endif + + + +// --------------------- Shader storage buffer ----------------------- + +#ifndef GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES +# define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#endif + +#ifndef GL_SHADER_STORAGE_BUFFER +# define GL_SHADER_STORAGE_BUFFER 0x90D2 +#endif + +#ifndef GL_SHADER_STORAGE_BUFFER_BINDING +# define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#endif + +#ifndef GL_SHADER_STORAGE_BUFFER_START +# define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#endif + +#ifndef GL_SHADER_STORAGE_BUFFER_SIZE +# define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#endif + +#ifndef GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS +# define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#endif + +#ifndef GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS +# define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#endif + +#ifndef GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS +# define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#endif + +#ifndef GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS +# define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#endif + +#ifndef GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS +# define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#endif + +#ifndef GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS +# define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#endif + +#ifndef GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS +# define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#endif + +#ifndef GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS +# define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#endif + +#ifndef GL_MAX_SHADER_STORAGE_BLOCK_SIZE +# define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#endif + +#ifndef GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT +# define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#endif + + +// Polygon mode +#ifndef GL_POINT +# define GL_POINT 0x1B00 +#endif + +#ifndef GL_LINE +# define GL_LINE 0x1B01 +#endif + +#ifndef GL_FILL +# define GL_FILL 0x1B02 +#endif + + +#ifndef GL_DEPTH_CLAMP +# define GL_DEPTH_CLAMP 0 +#endif + +// Blend functions +#ifndef GL_SRC1_COLOR +# define GL_SRC1_COLOR 0x88F9 +#endif + +#ifndef GL_ONE_MINUS_SRC1_COLOR +# define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#endif + +#ifndef GL_SOURCE1_ALPHA +# define GL_SOURCE1_ALPHA 0x8589 +#endif + +#ifndef GL_SRC1_ALPHA +# define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#endif + +#ifndef GL_ONE_MINUS_SRC1_ALPHA +# define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#endif + +/* ---------------------- GL_ARB_internalformat_query2 --------------------- */ + +#ifndef GL_INTERNALFORMAT_SUPPORTED +# define GL_INTERNALFORMAT_SUPPORTED 0x826F +#endif + +// --------------------- Framebuffer SRGB ----------------------- +#ifndef GL_FRAMEBUFFER_SRGB +# define GL_FRAMEBUFFER_SRGB 0x8DB9 +#endif + +// -------------------- Incomplete FBO error codes --------------- +#ifndef GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS +# define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#endif + +#ifndef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER +# define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#endif + +#ifndef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER +# define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#endif + + +// Define unsupported GL function stubs +template<typename T> +void UnsupportedGLFunctionStub( const T &Name ) +{ + LOG_ERROR_MESSAGE( Name, "() is not supported in this API!\n" ); +} + +#ifndef glGenProgramPipelines + #define LOAD_GEN_PROGRAM_PIPELINES + typedef void (* PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); + extern PFNGLGENPROGRAMPIPELINESPROC glGenProgramPipelines; +#endif + + +#ifndef glDeleteProgramPipelines + #define LOAD_GL_DELETE_PROGRAM_PIPELINES + typedef void (* PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint* pipelines); + extern PFNGLDELETEPROGRAMPIPELINESPROC glDeleteProgramPipelines; +#endif + +#ifndef glBindProgramPipeline + #define LOAD_GL_BIND_PROGRAM_PIPELINE + typedef void (* PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); + extern PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline; +#endif + +#ifndef glDrawElementsIndirect + #define LOAD_DRAW_ELEMENTS_INDIRECT + typedef void (* PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect); + extern PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect; +#endif + +#ifndef glDrawArraysIndirect + #define LOAD_DRAW_ARRAYS_INDIRECT + typedef void (* PFNGLDRAWARRAYSINDIRECTPROC)( GLenum mode, const GLvoid *indirect ); + extern PFNGLDRAWARRAYSINDIRECTPROC glDrawArraysIndirect; +#endif + +#ifndef glDispatchComputeIndirect + #define LOAD_DISPATCH_COMPUTE_INDIRECT + typedef void (* PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); + extern PFNGLDISPATCHCOMPUTEINDIRECTPROC glDispatchComputeIndirect; +#endif + +#ifndef glDrawElementsInstancedBaseVertexBaseInstance +# define glDrawElementsInstancedBaseVertexBaseInstance(...) UnsupportedGLFunctionStub("glDrawElementsInstancedBaseVertexBaseInstance") +#endif + +#ifndef glDrawElementsInstancedBaseVertex +# define glDrawElementsInstancedBaseVertex(...) UnsupportedGLFunctionStub("glDrawElementsInstancedBaseVertex") +#endif + +#ifndef glDrawElementsInstancedBaseInstance +# define glDrawElementsInstancedBaseInstance(...) UnsupportedGLFunctionStub("glDrawElementsInstancedBaseInstance") +#endif + +#ifndef glDrawArraysInstancedBaseInstance +# define glDrawArraysInstancedBaseInstance(...) UnsupportedGLFunctionStub("glDrawArraysInstancedBaseInstance") +#endif + +#ifndef glDrawElementsBaseVertex +# define glDrawElementsBaseVertex(...) UnsupportedGLFunctionStub("glDrawElementsBaseVertex") +#endif + +#ifndef glUseProgramStages + #define LOAD_GL_USE_PROGRAM_STAGES + typedef void (* PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); + extern PFNGLUSEPROGRAMSTAGESPROC glUseProgramStages; +#endif + +#ifndef glTexStorage1D +# define glTexStorage1D(...) UnsupportedGLFunctionStub("glTexStorage1D") +#endif + +#ifndef glTexSubImage1D +# define glTexSubImage1D(...) UnsupportedGLFunctionStub("glTexSubImage1D") +#endif + +#ifndef glTexStorage3DMultisample +# define glTexStorage3DMultisample(...) UnsupportedGLFunctionStub("glTexStorage3DMultisample") +#endif + +#ifndef glTexStorage2DMultisample + #define LOAD_GL_TEX_STORAGE_2D_MULTISAMPLE + typedef void (* PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + extern PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample; +#endif + +#ifndef glTextureView +# define glTextureView(...) UnsupportedGLFunctionStub("glTextureView") +#endif + +#ifndef glTexBuffer + #define LOAD_GL_TEX_BUFFER + typedef void (* PFNGLTEXBUFFERPROC) (GLenum, GLenum, GLuint); + extern PFNGLTEXBUFFERPROC glTexBuffer; +#endif + +#ifndef glProgramUniform1i + #define LOAD_GL_PROGRAM_UNIFORM_1I + typedef void (* PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint x); + extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i; +#endif + +#ifndef glGetProgramInterfaceiv + #define LOAD_GL_GET_PROGRAM_INTERFACEIV + typedef void (* PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint* params); + extern PFNGLGETPROGRAMINTERFACEIVPROC glGetProgramInterfaceiv; +#endif + +#ifndef glGetProgramResourceName + #define LOAD_GL_GET_PROGRAM_RESOURCE_NAME + typedef void (* PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar *name); + extern PFNGLGETPROGRAMRESOURCENAMEPROC glGetProgramResourceName; +#endif + +#ifndef glGetProgramResourceiv + #define LOAD_GL_GET_PROGRAM_RESOURCEIV + typedef void (* PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLint *params); + extern PFNGLGETPROGRAMRESOURCEIVPROC glGetProgramResourceiv; +#endif + +#ifndef glPolygonMode + #define LOAD_GL_POLYGON_MODE + typedef void (* PFNGLPOLYGONMODE) (GLenum face, GLenum mode); + extern PFNGLPOLYGONMODE glPolygonMode; +#endif + + +#ifndef glEnablei + #define LOAD_GL_ENABLEI + typedef void (* PFNGLENABLEIPROC) (GLenum, GLuint); + extern PFNGLENABLEIPROC glEnablei; +#endif + +#ifndef glBlendFuncSeparatei + #define LOAD_GL_BLEND_FUNC_SEPARATEI + typedef void (* PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + extern PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei; +#endif + +#ifndef glBlendEquationSeparatei + #define LOAD_GL_BLEND_EQUATION_SEPARATEI + typedef void (* PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); + extern PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei; +#endif + +#ifndef glDisablei + #define LOAD_GL_DISABLEI + typedef void (* PFNGLDISABLEIPROC) (GLenum, GLuint); + extern PFNGLDISABLEIPROC glDisablei; +#endif + +#ifndef glColorMaski + #define LOAD_GL_COLOR_MASKI + typedef void (* PFNGLCOLORMASKIPROC) (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); + extern PFNGLCOLORMASKIPROC glColorMaski; +#endif + +#ifndef glViewportIndexedf + #define LOAD_GL_VIEWPORT_INDEXEDF + typedef void (* PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); + extern PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf; +#endif + +#ifndef glScissorIndexed + #define LOAD_GL_SCISSOR_INDEXED + typedef void (* PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); + extern PFNGLSCISSORINDEXEDPROC glScissorIndexed; +#endif + +#ifndef glFramebufferTexture + #define LOAD_GL_FRAMEBUFFER_TEXTURE + typedef void (* PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum, GLenum, GLuint, GLint); + extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; +#endif + +#ifndef glFramebufferTexture1D + #define LOAD_GL_FRAMEBUFFER_TEXTURE_1D + typedef void (* PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; +#endif + +#ifndef glFramebufferTexture3D + #define LOAD_GL_FRAMEBUFFER_TEXTURE_3D + typedef void (* PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); + extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; +#endif + +#ifndef glCopyImageSubData + #define LOAD_GL_COPY_IMAGE_SUB_DATA + typedef void (* PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + extern PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData; +#endif + +void LoadGLFunctions();
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h new file mode 100644 index 00000000..a5b381f8 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h @@ -0,0 +1,241 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +namespace Diligent +{ + +inline GLenum PrimitiveTopologyToGLTopology(PRIMITIVE_TOPOLOGY PrimTopology) +{ + switch(PrimTopology) + { + case PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return GL_TRIANGLES; break; + case PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP; break; + case PRIMITIVE_TOPOLOGY_POINT_LIST: return GL_POINTS; break; + case PRIMITIVE_TOPOLOGY_LINE_LIST: return GL_LINES; break; + default: return 0; + } +} + +inline GLenum TypeToGLType(VALUE_TYPE Value) +{ + switch(Value) + { + case VT_INT8: return GL_BYTE; break; + case VT_INT16: return GL_SHORT; break; + case VT_INT32: return GL_INT; break; + case VT_UINT8: return GL_UNSIGNED_BYTE; break; + case VT_UINT16: return GL_UNSIGNED_SHORT; break; + case VT_UINT32: return GL_UNSIGNED_INT; break; + case VT_FLOAT32: return GL_FLOAT; break; + default: return 0; + } +} + +inline GLenum UsageToGLUsage(USAGE Usage) +{ + // http://www.informit.com/articles/article.aspx?p=2033340&seqNum=2 + switch(Usage) + { + case USAGE_STATIC: return GL_STATIC_DRAW; + case USAGE_DEFAULT: return GL_DYNAMIC_DRAW; + case USAGE_DYNAMIC: return GL_STREAM_DRAW; + case USAGE_CPU_ACCESSIBLE: return GL_DYNAMIC_READ; + default: UNEXPECTED( "Unknow usage" ); return 0; + } +} + +inline void FilterTypeToGLFilterType(FILTER_TYPE Filter, GLenum &GLFilter, Bool &bIsAnisotropic, Bool &bIsComparison) +{ + switch(Filter) + { + case FILTER_TYPE_UNKNOWN: + UNEXPECTED( "Unspecified filter type" ); + bIsAnisotropic = false; + bIsComparison = false; + GLFilter = GL_NEAREST; + break; + + case FILTER_TYPE_POINT: + bIsAnisotropic = false; + bIsComparison = false; + GLFilter = GL_NEAREST; + break; + + case FILTER_TYPE_LINEAR: + bIsAnisotropic = false; + bIsComparison = false; + GLFilter = GL_LINEAR; + break; + + case FILTER_TYPE_ANISOTROPIC: + bIsAnisotropic = true; + bIsComparison = false; + GLFilter = GL_LINEAR; + break; + + case FILTER_TYPE_COMPARISON_POINT: + bIsAnisotropic = false; + bIsComparison = true; + GLFilter = GL_NEAREST; + break; + + case FILTER_TYPE_COMPARISON_LINEAR: + bIsAnisotropic = false; + bIsComparison = true; + GLFilter = GL_LINEAR; + break; + + case FILTER_TYPE_COMPARISON_ANISOTROPIC: + bIsAnisotropic = true; + bIsComparison = true; + GLFilter = GL_LINEAR; + break; + + default: + bIsAnisotropic = false; + bIsComparison = false; + UNEXPECTED( "Unknown filter type" ); + GLFilter = GL_NEAREST; + break; + } +} + +GLenum TexFormatToGLInternalTexFormat(TEXTURE_FORMAT TexFormat, Uint32 BindFlags = 0); +GLenum CorrectGLTexFormat(GLenum GLTexFormat, Uint32 BindFlags); + +inline GLenum TexAddressModeToGLAddressMode(TEXTURE_ADDRESS_MODE Mode) +{ + switch(Mode) + { + case TEXTURE_ADDRESS_UNKNOWN: UNEXPECTED( "Texture address mode is not specified" ); return GL_CLAMP_TO_EDGE; + case TEXTURE_ADDRESS_WRAP: return GL_REPEAT; + case TEXTURE_ADDRESS_MIRROR: return GL_MIRRORED_REPEAT; + case TEXTURE_ADDRESS_CLAMP: return GL_CLAMP_TO_EDGE; + case TEXTURE_ADDRESS_BORDER: return GL_CLAMP_TO_BORDER; + case TEXTURE_ADDRESS_MIRROR_ONCE: return GL_MIRROR_CLAMP_TO_EDGE; // only available with OpenGL 4.4 + // This mode seems to be different from D3D11_TEXTURE_ADDRESS_MIRROR_ONCE + // The texture coord is clamped to the [-1, 1] range, but mirrors the + // negative direction with the positive. Basically, it acts as + // GL_CLAMP_TO_EDGE except that it takes the absolute value of the texture + // coordinates before clamping. + default: UNEXPECTED( "Unknown texture address mode" ); return GL_CLAMP_TO_EDGE; + } +} + +inline GLenum CompareFuncToGLCompareFunc(COMPARISON_FUNCTION Func) +{ + switch(Func) + { + case COMPARISON_FUNC_UNKNOW: UNEXPECTED( "Comparison function is not specified" ); return GL_ALWAYS; + case COMPARISON_FUNC_NEVER: return GL_NEVER; + case COMPARISON_FUNC_LESS: return GL_LESS; + case COMPARISON_FUNC_EQUAL: return GL_EQUAL; + case COMPARISON_FUNC_LESS_EQUAL: return GL_LEQUAL; + case COMPARISON_FUNC_GREATER: return GL_GREATER; + case COMPARISON_FUNC_NOT_EQUAL: return GL_NOTEQUAL; + case COMPARISON_FUNC_GREATER_EQUAL: return GL_GEQUAL; + case COMPARISON_FUNC_ALWAYS: return GL_ALWAYS; + default: UNEXPECTED( "Unknown comparison func" ); return GL_ALWAYS; + } +} + +struct NativePixelAttribs +{ + GLenum PixelFormat; + GLenum DataType; + Bool IsCompressed; + explicit NativePixelAttribs(GLenum _PixelFormat = 0, GLenum _DataType = 0, Bool _IsCompressed = False) : + PixelFormat(_PixelFormat), + DataType(_DataType), + IsCompressed(_IsCompressed) + {} +}; + +inline Uint32 GetNumPixelFormatComponents(GLenum Format) +{ + switch(Format) + { + case GL_RGBA: + case GL_RGBA_INTEGER: + return 4; + + case GL_RGB: + case GL_RGB_INTEGER: + return 3; + + case GL_RG: + case GL_RG_INTEGER: + return 2; + + case GL_RED: + case GL_RED_INTEGER: + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + return 1; + + default: UNEXPECTED( "Unknonw pixel format" ); return 0; + }; +} + +inline Uint32 GetPixelTypeSize(GLenum Type) +{ + switch(Type) + { + case GL_FLOAT: return sizeof(GLfloat); + + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL_UNSIGNED_INT_24_8: + case GL_UNSIGNED_INT_5_9_9_9_REV: + case GL_UNSIGNED_INT: return sizeof(GLuint); + + case GL_INT: return sizeof(GLint); + case GL_HALF_FLOAT: return sizeof(GLhalf); + + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_SHORT: return sizeof(GLushort); + + case GL_SHORT: return sizeof(GLshort); + case GL_UNSIGNED_BYTE: return sizeof(GLubyte); + case GL_BYTE: return sizeof(GLbyte); + + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:return sizeof(GLfloat) + sizeof(GLuint); + + default: UNEXPECTED( "Unknonw pixel type" ); return 0; + } +} + +NativePixelAttribs GetNativePixelTransferAttribs(TEXTURE_FORMAT TexFormat); +GLenum AccessFlags2GLAccess( Uint32 UAVAccessFlags ); +GLenum TypeToGLTexFormat( VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized ); +GLenum StencilOp2GlStencilOp( STENCIL_OP StencilOp ); +GLenum BlendFactor2GLBlend( BLEND_FACTOR bf ); +GLenum BlendOperation2GLBlendOp( BLEND_OPERATION BlendOp ); + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/HLSL2GLSLConverter.h b/Graphics/GraphicsEngineOpenGL/include/HLSL2GLSLConverter.h new file mode 100644 index 00000000..6877cc47 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/HLSL2GLSLConverter.h @@ -0,0 +1,424 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "Shader.h" +#include "HashUtils.h" +#include <list> +#include <unordered_set> + +namespace Diligent +{ + struct FunctionStubHashKey + { + FunctionStubHashKey(const String& _Obj, const String& _Func, Uint32 _NumArgs) : + Object(_Obj), + Function(_Func), + NumArguments(_NumArgs) + { + } + + FunctionStubHashKey(const Char* _Obj, const Char* _Func, Uint32 _NumArgs) : + Object(_Obj), + Function(_Func), + NumArguments(_NumArgs) + { + } + + FunctionStubHashKey( FunctionStubHashKey && Key ) : + Object(std::move(Key.Object)), + Function(std::move(Key.Function)), + NumArguments(Key.NumArguments) + { + } + + bool operator==(const FunctionStubHashKey& rhs)const + { + return Object == rhs.Object && + Function == rhs.Function && + NumArguments == rhs.NumArguments; + } + + HashMapStringKey Object; + HashMapStringKey Function; + Uint32 NumArguments; + }; +} + +namespace std +{ + template<>struct hash < Diligent::FunctionStubHashKey > + { + size_t operator()( const Diligent::FunctionStubHashKey &Key ) const + { + return ComputeHash(Key.Object, Key.Function, Key.NumArguments); + } + }; +} + +namespace Diligent +{ + class HLSL2GLSLConverter + { + public: + HLSL2GLSLConverter(IShaderSourceInputStreamFactory *pSourceStreamFactory); + String Convert(const Char* HLSLSource, size_t NumSymbols, const Char* EntryPoint, SHADER_TYPE ShaderType); + + private: + void InsertIncludes(String &GLSLSource); + + void ProcessShaderDeclaration(const Char* EntryPoint, SHADER_TYPE ShaderType); + + IShaderSourceInputStreamFactory* m_pSourceStreamFactory; + + struct HLSLObjectInfo + { + String GLSLType; // sampler2D, sampler2DShadow, image2D, etc. + Uint32 NumComponents; // 0,1,2,3 or 4 + // Texture2D<float4> -> 4 + // Texture2D<uint> -> 1 + // Texture2D -> 0 + HLSLObjectInfo( const String& Type, Uint32 NComp ) : + GLSLType( Type ), + NumComponents( NComp ) + {} + }; + typedef std::unordered_map<HashMapStringKey, HLSLObjectInfo> ObjectsTypeHashType; + + // Stack of parsed objects, for every scope level. + // There are currently only two levels: + // level 0 - global scope, contains all global objects + // (textures, buffers) + // level 1 - function body, contains all objects + // defined as function arguments + std::vector< ObjectsTypeHashType > m_Objects; + + struct GLSLStubInfo + { + String Name; + String Swizzle; + GLSLStubInfo( const String& _Name, const char* _Swizzle ) : + Name( _Name ), + Swizzle( _Swizzle ) + {} + }; + // Hash map that maps GLSL object, method and number of arguments + // passed to the original function, to the GLSL stub function + // Example: {"sampler2D", "Sample", 2} -> {"Sample_2", "_SWIZZLE"} + std::unordered_map<FunctionStubHashKey, GLSLStubInfo> m_GLSLStubs; + + + void Tokenize(const String &Source); + + String BuildGLSLSource(); + + enum class TokenType + { + Undefined, + PreprocessorDirective, + Operator, + OpenBrace, + ClosingBrace, + OpenBracket, + ClosingBracket, + OpenStaple, + ClosingStaple, + OpenAngleBracket, + ClosingAngleBracket, + Identifier, + NumericConstant, + Semicolon, + Comma, + cbuffer, + Texture1D, + Texture1DArray, + Texture2D, + Texture2DArray, + Texture3D, + TextureCube, + TextureCubeArray, + Texture2DMS, + Texture2DMSArray, + RWTexture1D, + RWTexture1DArray, + RWTexture2D, + RWTexture2DArray, + RWTexture3D, + SamplerState, + SamplerComparisonState, + BuiltInType, + TextBlock, + _struct, + Assignment, + ComparisonOp, + BooleanOp, + BitwiseOp, + IncDecOp, + MathOp, + FlowControl + }; + + struct TokenInfo + { + TokenType Type; + String Literal; + String Delimiter; + TokenInfo(TokenType _Type = TokenType :: Undefined, + const Char* _Literal = "", + const Char* _Delimiter = "") : + Type( _Type ), + Literal( _Literal ), + Delimiter(_Delimiter) + {} + }; + + typedef std::list<TokenInfo> TokenListType; + typedef std::unordered_map<String, bool> SamplerHashType; + + const HLSLObjectInfo *FindHLSLObject(const String &Name ); + + void ProcessObjectMethods(const TokenListType::iterator &ScopeStart, const TokenListType::iterator &ScopeEnd); + + void ProcessRWTextures(const TokenListType::iterator &ScopeStart, const TokenListType::iterator &ScopeEnd); + + void ProcessAtomics(const TokenListType::iterator &ScopeStart, + const TokenListType::iterator &ScopeEnd); + + void ProcessScope(const TokenListType::iterator &ScopeStart, + const TokenListType::iterator &ScopeEnd); + + void ProcessConstantBuffer(TokenListType::iterator &Token); + void ParseSamplers(TokenListType::iterator &ScopeStart, SamplerHashType &SamplersHash); + void ProcessTextureDeclaration(TokenListType::iterator &Token, const std::vector<SamplerHashType> &SamplersHash, ObjectsTypeHashType &Objects); + bool ProcessObjectMethod(TokenListType::iterator &Token, const TokenListType::iterator &ScopeStart, const TokenListType::iterator &ScopeEnd); + Uint32 CountFunctionArguments(TokenListType::iterator &Token, const TokenListType::iterator &ScopeEnd); + bool ProcessRWTextureStore(TokenListType::iterator &Token, const TokenListType::iterator &ScopeEnd); + void RemoveFlowControlAttribute(TokenListType::iterator &Token); + void RemoveSemantics(); + void RemoveSpecialShaderAttributes(); + void RemoveSemanticsFromBlock(TokenListType::iterator &Token, TokenType OpenBracketType, TokenType ClosingBracketType, bool IsStruct); + + // IteratorType may be String::iterator or String::const_iterator. + // While iterator is convertible to const_iterator, + // iterator& cannot be converted to const_iterator& (Microsoft compiler allows + // such conversion, while gcc does not) + template<typename IteratorType> + String PrintTokenContext(IteratorType &TargetToken, Int32 NumAdjacentLines); + + struct ShaderParameterInfo + { + enum class StorageQualifier + { + Unknown, + In, + Out + }storageQualifier; + String Type; + String Name; + String Semantic; + + ShaderParameterInfo() : + storageQualifier(StorageQualifier::Unknown) + {} + }; + void ParseShaderParameters( TokenListType::iterator &Token, std::vector<ShaderParameterInfo>& Params ); + void ProcessFragmentShaderArguments( std::vector<ShaderParameterInfo>& Params, + String &GlobalVariables, + String &Epilogue, + String &Prologue ); + void ProcessVertexShaderArguments( std::vector<ShaderParameterInfo>& Params, + String &GlobalVariables, + String &Epilogue, + String &Prologue ); + void ProcessComputeShaderArguments( TokenListType::iterator &TypeToken, + std::vector<ShaderParameterInfo>& Params, + String &GlobalVariables, + String &Prologue ); + + void FindClosingBracket( TokenListType::iterator &Token, const TokenListType::iterator &ScopeEnd, TokenType OpenBracketType, TokenType ClosingBracketType ); + + void ProcessReturnStatements( TokenListType::iterator &Token, const String &Epilogue, const char *EntryPoint ); + + // Tokenized source code + TokenListType m_Tokens; + + // HLSL keyword->token info hash map + // Example: "Texture2D" -> TokenInfo(TokenType::Texture2D, "Texture2D") + std::unordered_map<HashMapStringKey, TokenInfo> m_HLSLKeywords; + + // Set of all GLSL image types (image1D, uimage1D, iimage1D, image2D, ... ) + std::unordered_set<HashMapStringKey> m_ImageTypes; + + // Set of all HLSL atomic operations (InterlockedAdd, InterlockedOr, ...) + std::unordered_set<HashMapStringKey> m_AtomicOperations; + }; +} + +// Intro +// DirectX and OpenGL use different shading languages. While mostly being very similar, +// the language syntax differ substantially in some places. Having two versions of each +// shader is clearly not an option for real projects. Maintaining intermediate representation +// that translates to both languages is one solution, but it might complicate shader development +// and debugging. +// +// HLSL converter allows HLSL shader files to be converted into GLSL source. +// The entire shader development can thus be performed using HLSL tools. Since no intermediate +// representation is used, shader files can be directly compiled by HLSL compiler. +// All tools available for HLSL shader devlopment, analysis and optimization can be +// used. The source can then be transaprently converted to GLSL. +// +// +// Using HLSL Converter +// * The following rules are used to convert HLSL texture declaration into GLSL sampler: +// - HLSL texture dimension defines GLSL sampler dimension: +// - Texture2D -> sampler2D +// - TextureCube -> samplerCube +// - HLSL texture component type defines GLSL sampler type. If no type is specified, float4 is assumed: +// - Texture2D<float> -> sampler2D +// - Texture3D<uint4> -> usampler3D +// - Texture2DArray<int2> -> isampler2DArray +// - Texture2D -> sampler2D +// - To distinguish if sampler should be shadow or not, the converter tries to find <Texture Name>_sampler +// among samplers (global variables and function arguments). If the sampler type is comparison, +// the texture is converted to shadow sampler. If sampler state is either not comparison or not found, +// regular sampler is used. +// Examples: +// - Texture2D g_ShadowMap; -> sampler2DShadow g_ShadowMap; +// SamplerComparisonState g_ShadowMap_sampler; +// - Texture2D g_Tex2D; -> sampler2D g_Tex2D; +// SamplerState g_Tex2D_sampler; +// Texture3D g_Tex3D; -> sampler3D g_Tex3D; +// +// * GLSL requires format to be specified for all images allowing writes. HLSL converter allows GLSL image +// format specification inside the special comment block: +// Example: +// RWTexture2D<float /* format=r32f */ > Tex2D; + +// Requirements: +// * Shader entry points must be declared as void functions with all outputs listed +// as out variables +// ** Members of structures cannot have system-value semantic (such as SV_Position). +// Such variables must be declared as direct shader input/output +// * GLSL allows samplers to be declared as global variables or function arguments only. +// It does not allow local variables of sampler type. +// +// Important notes/known issues: +// +// * GLSL compiler does not handle float3 structure members correctly. It is +// strongly suggested not to use this type in structure definitions +// +// * At least NVidia GLSL compiler does not apply layout(row_major) to +// structure members. By default, all matrices in both HLSL and GLSL +// are column major +// +// * GLSL compiler does not properly handle structs passed as function arguments!!!! +// struct MyStruct +// { +// matrix Matr; +// } +// void Func(in MyStruct S) +// { +// ... +// mul(f4PosWS, S.Matr); <--- This will not work!!! +// } +// DO NOT pass structs to functions, use only built-in types!!! +// +// * GLSL does not support most of the implicit type conversions. The following are some +// examples of required modifications to HLSL code: +// ** float4 vec = 0; -> float4 vec = float4(0.0, 0.0, 0.0, 0.0); +// ** float x = 0; -> float x = 0.0; +// ** uint x = 0; -> uint x = 0u; +// ** GLES is immensely strict about type conversions. For instance, +// this code will produce compiler error: float4(0, 0, 0, 0) +// It must be written as float4(0.0, 0.0, 0.0, 0.0) +// * GLSL does not support relational and boolean operations on vector types: +// ** float2 p = float2(1.0,2.0), q = float2(3.0,4.0); +// bool2 b = x < y; -> Error +// all(p<q) -> Error +// ** To facilitate relational and boolean operations on vector types, the following +// functions are predefined: +// - Less +// - LessEqual +// - Greater +// - GreaterEqual +// - Equal +// - NotEqual +// - Not +// - And +// - Or +// - BoolToFloat +// ** Examples: +// bool2 b = x < y; -> bool2 b = Less(x, y); +// all(p>=q) -> all( GreaterEqual(p,q) ) +// +// * When accessing elements of an HLSL matrix, the first index is always row: +// mat[row][column] +// In GLSL, the first index is always column: +// mat[column][row] +// MATRIX_ELEMENT(mat, row, col) macros is provided to facilitate matrix element retrieval + +// * The following functions do not have counterparts in GLSL and should be avoided: +// ** Texture2DArray.SampleCmpLevelZero() +// ** TextureCube.SampleCmpLevelZero() +// ** TextureCubeArray.SampleCmpLevelZero() + + +// * Shader converter creates shader interface blocks to process non-system generated +// input/output parameters. For instance, to process Out parameter of the vertex +// shader below +// +// struct VSOutput{ ... }; +// void VertexShader(out VSOutput Out){...} +// +// the following interface block will be created: +// +// out _IntererfaceBlock0 +// { +// VSOutput Out; +// }; +// +// OpenGL requires that interface block definitions in different shader stages +// must match exaclty: they must define the exact same variables (type/array count +// and NAME), in the exact same order. Since variable names must match, this +// effectively means that shader input/output parameter names must also match +// exactly. This limitation seems to be relaxed in desktop GL and some GLES. +// For instance, the following code works fine on Desktop GL and on Intel GLES, +// but fails on NVidia GLES: +// +// struct VSOutput{ ... }; +// void VertexShader(out VSOutput Out){...} +// void PixelShader(in VSOutput In){...} +// +// To make it run on NVidia GLES, shader intput/output parameter names must +// be exactly the same: +// +// struct VSOutput{ ... }; +// void VertexShader(out VSOutput VSOut){...} +// void PixelShader(in VSOutput VSOut){...} +// +// Moreover, even when fragment shader does not actually use the parameter, +// it still must be declared +// +// If the requirements above are not met, the shaders are still compiled successfuly, +// but glDraw*() command fails with useless error 1282 (IVALID_OPERATION)
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/include/ProgramPipelineCache.h b/Graphics/GraphicsEngineOpenGL/include/ProgramPipelineCache.h new file mode 100644 index 00000000..a7b62f49 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/ProgramPipelineCache.h @@ -0,0 +1,102 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "RenderDevice.h" +#include "HashUtils.h" +#include "GLProgram.h" + +namespace Diligent +{ + +class ProgramPipelineCache +{ +public: + ProgramPipelineCache( class RenderDeviceGLImpl *pRenderDeviceOpenGL ); + ~ProgramPipelineCache(); + + struct CacheElementType + { + GLObjectWrappers::GLPipelineObj Pipeline; + GLProgram Program; + CacheElementType() : + Pipeline( false ), + Program( false ) + {} + CacheElementType( CacheElementType &&Elem ) : + Pipeline( std::move( Elem.Pipeline ) ), + Program( std::move( Elem.Program ) ) + {} + }; + + CacheElementType &GetProgramPipeline( RefCntAutoPtr<IShader> *ppShaders, Uint32 NumShadersToSet ); + void OnDestroyShader(IShader *pShader); + +private: + friend class RenderDeviceGLImpl; + ThreadingTools::LockFlag m_CacheLockFlag; + + // This structure is used as the key to find VAO + struct PipelineCacheKey + { + IShader *pVS; + IShader *pGS; + IShader *pPS; + IShader *pDS; + IShader *pHS; + IShader *pCS; + + bool operator == (const PipelineCacheKey &Key)const + { + return pVS == Key.pVS && + pGS == Key.pGS && + pPS == Key.pPS && + pDS == Key.pDS && + pHS == Key.pHS && + pCS == Key.pCS; + } + }; + + struct PipelineCacheHashFunc + { + std::size_t operator() ( const PipelineCacheKey& Key )const + { + std::size_t Seed = 0; + if(Key.pVS)HashCombine(Seed, Key.pVS); + if(Key.pGS)HashCombine(Seed, Key.pGS); + if(Key.pPS)HashCombine(Seed, Key.pPS); + if(Key.pDS)HashCombine(Seed, Key.pDS); + if(Key.pHS)HashCombine(Seed, Key.pHS); + if(Key.pCS)HashCombine(Seed, Key.pCS); + return Seed; + } + }; + + bool m_bIsProgramPipelineSupported; + + std::unordered_map<PipelineCacheKey, CacheElementType, PipelineCacheHashFunc> m_Cache; + std::unordered_multimap<IShader*, PipelineCacheKey> m_ShaderToKey; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/RasterizerStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/RasterizerStateGLImpl.h new file mode 100644 index 00000000..6e28893a --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/RasterizerStateGLImpl.h @@ -0,0 +1,46 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BaseInterfacesGL.h" +#include "RasterizerStateGL.h" +#include "RasterizerStateBase.h" +#include "RenderDevice.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IRasterizerStateGL interface +class RasterizerStateGLImpl : public RasterizerStateBase<IRasterizerStateGL, IGLDeviceBaseInterface> +{ +public: + typedef RasterizerStateBase<IRasterizerStateGL, IGLDeviceBaseInterface> TRasterizerStateBase; + + RasterizerStateGLImpl(class IRenderDevice *pDeviceGL, const RasterizerStateDesc& RasterizerStateDesc, bool bIsDeviceInternal = false ); + ~RasterizerStateGLImpl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h new file mode 100644 index 00000000..eddcf0b6 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "RenderDeviceGLImpl.h" + +namespace Diligent +{ + +class RenderDeviceGLESImpl : public RenderDeviceGLImpl +{ +public: + RenderDeviceGLESImpl( const ContextInitInfo &InitInfo ); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual bool Invalidate(); + + virtual void Suspend(); + + virtual EGLint Resume( ANativeWindow* window ); +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h new file mode 100644 index 00000000..411df027 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h @@ -0,0 +1,131 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "RenderDeviceBase.h" + +#ifdef _WINDOWS +#include "GLContextWindows.h" +#endif + +#ifdef ANDROID +#include "GLContextAndroid.h" +#endif + +#include "VAOCache.h" +#include "ProgramPipelineCache.h" +#include "BaseInterfacesGL.h" +#include "FBOCache.h" +#include "TexRegionRender.h" + +enum class GPU_VENDOR +{ + UNKNOWN, + INTEL, + ATI, + NVIDIA +}; + +struct GPUInfo +{ + GPU_VENDOR Vendor; + GPUInfo() : + Vendor( GPU_VENDOR::UNKNOWN ) + {} +}; + +namespace Diligent +{ + +/// Implementation of the render device interface in OpenGL +class RenderDeviceGLImpl : public RenderDeviceBase<IGLDeviceBaseInterface> +{ +public: + typedef RenderDeviceBase<IGLDeviceBaseInterface> TRenderDeviceBase; + + RenderDeviceGLImpl( const ContextInitInfo &InitInfo ); + ~RenderDeviceGLImpl(); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + void CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBufferLayout, bool bIsDeviceInternal); + virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBufferLayout)override; + + void CreateVertexDescription( const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc, bool bIsDeviceInternal ); + virtual void CreateVertexDescription( const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc )override; + + void CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader, bool bIsDeviceInternal ); + virtual void CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader)override; + + void CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture, bool bIsDeviceInternal); + virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture)override; + + void CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler, bool bIsDeviceInternal); + virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler)override; + + void CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState, bool bIsDeviceInternal ); + virtual void CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState )override; + + void CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState, bool bIsDeviceInternal); + virtual void CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState )override; + + void CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState, bool bIsDeviceInternal ); + virtual void CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState )override; + + const GPUInfo& GetGPUInfo(){ return m_GPUInfo; } + +protected: + friend class DeviceContextGLImpl; + friend class TextureBaseGL; + friend class VertexDescGLImpl; + friend class ShaderGLImpl; + friend class BufferGLImpl; + friend class TextureViewGLImpl; + friend class SwapChainGLImpl; + + // Must be the first member because its constructor initializes OpenGL + GLContext m_GLContext; + + std::unordered_set<String> m_ExtensionStrings; + + VAOCache m_VAOCache; + FBOCache m_FBOCache; + ProgramPipelineCache m_PipelineCache; + + GPUInfo m_GPUInfo; + + // Any draw command fails if no VAO is bound. We will use this empty + // VAO for draw commands with null input layout, such as these that + // only use VertexID as input. + GLObjectWrappers::GLVertexArrayObj m_EmptyVAO; + + TexRegionRender m_TexRegionRender; + +private: + virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat ); + bool CheckExtension(const Char *ExtensionString); + void FlagSupportedTexFormats(); + void QueryDeviceCaps(); +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h new file mode 100644 index 00000000..20b9f505 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h @@ -0,0 +1,52 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BaseInterfacesGL.h" +#include "SamplerGL.h" +#include "SamplerBase.h" +#include "RenderDevice.h" +#include "GLObjectWrapper.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::ISamplerGL interface +class SamplerGLImpl : public SamplerBase<ISamplerGL, IGLDeviceBaseInterface> +{ +public: + typedef SamplerBase<ISamplerGL, IGLDeviceBaseInterface> TSamplerBase; + + SamplerGLImpl( class RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal = false ); + ~SamplerGLImpl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + const GLObjectWrappers::GLSamplerObj& GetHandle(){ return m_GlSampler; } + +private: + GLObjectWrappers::GLSamplerObj m_GlSampler; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h new file mode 100644 index 00000000..b4f20f21 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h @@ -0,0 +1,105 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BaseInterfacesGL.h" +#include "ShaderGL.h" +#include "ShaderBase.h" +#include "RenderDevice.h" +#include "GLObjectWrapper.h" +#include "GLProgram.h" +#include "HashUtils.h" + +namespace Diligent +{ + +inline GLenum GetGLShaderType(SHADER_TYPE ShaderType) +{ + switch(ShaderType) + { + case SHADER_TYPE_VERTEX: return GL_VERTEX_SHADER; break; + case SHADER_TYPE_PIXEL: return GL_FRAGMENT_SHADER; break; + case SHADER_TYPE_GEOMETRY: return GL_GEOMETRY_SHADER; break; + case SHADER_TYPE_HULL: return GL_TESS_CONTROL_SHADER; break; + case SHADER_TYPE_DOMAIN: return GL_TESS_EVALUATION_SHADER; break; + case SHADER_TYPE_COMPUTE: return GL_COMPUTE_SHADER; break; + default: return 0; + } +} + +inline GLenum ShaderTypeToGLShaderBit(SHADER_TYPE ShaderType) +{ + switch(ShaderType) + { + case SHADER_TYPE_VERTEX: return GL_VERTEX_SHADER_BIT; break; + case SHADER_TYPE_PIXEL: return GL_FRAGMENT_SHADER_BIT; break; + case SHADER_TYPE_GEOMETRY: return GL_GEOMETRY_SHADER_BIT; break; + case SHADER_TYPE_HULL: return GL_TESS_CONTROL_SHADER_BIT; break; + case SHADER_TYPE_DOMAIN: return GL_TESS_EVALUATION_SHADER_BIT; break; + case SHADER_TYPE_COMPUTE: return GL_COMPUTE_SHADER_BIT; break; + default: return 0; + } +} + +/// Implementation of the Diligent::IShaderGL interface +class ShaderGLImpl : public ShaderBase<IShaderGL, IGLDeviceBaseInterface> +{ +public: + typedef ShaderBase<IShaderGL, IGLDeviceBaseInterface> TShaderBase; + + ShaderGLImpl( class RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &ShaderCreationAttribs, bool bIsDeviceInternal = false ); + ~ShaderGLImpl(); + + virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags )override; + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual IShaderVariable* GetShaderVariable( const Char* Name )override; + +private: + struct CGLShaderVariable : ShaderVariableBase + { + CGLShaderVariable( ShaderGLImpl *pShader, GLProgram::GLProgramVariableBase &ProgVar ) : + ShaderVariableBase( pShader ), + ProgramVar(ProgVar) + {} + + virtual void Set( IDeviceObject *pObject )override + { + ProgramVar.pResource = pObject; + } + private: + GLProgram::GLProgramVariableBase &ProgramVar; + }; + + friend class ProgramPipelineCache; + friend class DeviceContextGLImpl; + GLProgram m_GlProgObj; // Used if program pipeline supported + GLObjectWrappers::GLShaderObj m_GLShaderObj; // Used if program pipelines are not supported + + /// Hash map to look up shader variables by name. + std::unordered_map<Diligent::HashMapStringKey, CGLShaderVariable> m_VariableHash; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h new file mode 100644 index 00000000..582a80d3 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "SwapChainGL.h" +#include "SwapChainBase.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::ISwapChainGL interface +class SwapChainGLImpl : public SwapChainBase<ISwapChainGL> +{ +public: + typedef SwapChainBase<ISwapChainGL> TSwapChainBase; + + SwapChainGLImpl(const SwapChainDesc& SwapChainDesc, + class RenderDeviceGLImpl* pRenderDeviceGL, + class DeviceContextGLImpl* pImmediateContextGL); + ~SwapChainGLImpl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual void Present(); + + virtual void Resize( Uint32 NewWidth, Uint32 NewHeight ); +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h new file mode 100644 index 00000000..a16ea719 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h @@ -0,0 +1,66 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +namespace Diligent +{ + +// Helper class to facilitate texture copying by rendering +class TexRegionRender +{ +public: + TexRegionRender(class RenderDeviceGLImpl *pDeviceGL); + void SetStates(class DeviceContextGLImpl *pCtxGL); + void RestoreStates(class DeviceContextGLImpl *pCtxGL); + void Render(class DeviceContextGLImpl *pCtxGL, + ITextureView *pSrcSRV, + TEXTURE_TYPE TexType, + TEXTURE_FORMAT TexFormat, + Int32 DstToSrcXOffset, + Int32 DstToSrcYOffset, + Int32 SrcZ, + Int32 SrcMipLevel); + +private: + Diligent::RefCntAutoPtr<IShader> m_pVertexShader; + Diligent::RefCntAutoPtr<IShader> m_pFragmentShaders[TEXTURE_TYPE_NUM_TYPES * 3]; + Diligent::RefCntAutoPtr<IBuffer> m_pConstantBuffer; + Diligent::RefCntAutoPtr<IRasterizerState> m_pSolidFillNoCullRS; + Diligent::RefCntAutoPtr<IDepthStencilState> m_pDisableDetphDS; + Diligent::RefCntAutoPtr<IBlendState> m_pDefaultBS; + + Diligent::RefCntAutoPtr<IRasterizerState> m_pOrigRS; + Diligent::RefCntAutoPtr<IDepthStencilState> m_pOrigDS; + Uint32 m_OrigStencilRef; + Diligent::RefCntAutoPtr<IBlendState> m_pOrigBS; + float m_OrigBlendFactors[4]; + Uint32 m_OrigSamplesBlendMask; + Uint32 m_NumRenderTargets; + ITextureView *m_pOrigRTVs[MaxRenderTargets]; + Diligent::RefCntAutoPtr<ITextureView> m_pOrigDSV; + std::vector<IShader*> m_pOrigShaders; + std::vector<Viewport> m_OrigViewports; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h new file mode 100644 index 00000000..707d91c3 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h @@ -0,0 +1,48 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TextureBaseGL.h" + +namespace Diligent +{ + +class Texture1DArray_OGL : public TextureBaseGL +{ +public: + Texture1DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false); + ~Texture1DArray_OGL(); + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); + virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint ); + +private: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h new file mode 100644 index 00000000..33b9a780 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h @@ -0,0 +1,48 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TextureBaseGL.h" + +namespace Diligent +{ + +class Texture1D_OGL : public TextureBaseGL +{ +public: + Texture1D_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false); + ~Texture1D_OGL(); + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); + virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint ); + +private: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h new file mode 100644 index 00000000..9c7c896f --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h @@ -0,0 +1,48 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TextureBaseGL.h" + +namespace Diligent +{ + +class Texture2DArray_OGL : public TextureBaseGL +{ +public: + Texture2DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false ); + ~Texture2DArray_OGL(); + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); + virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint ); + +private: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h new file mode 100644 index 00000000..ab9225b9 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h @@ -0,0 +1,48 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TextureBaseGL.h" + +namespace Diligent +{ + +class Texture2D_OGL : public TextureBaseGL +{ +public: + Texture2D_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false); + ~Texture2D_OGL(); + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); + virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint ); + +private: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h new file mode 100644 index 00000000..83e9a257 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h @@ -0,0 +1,48 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TextureBaseGL.h" + +namespace Diligent +{ + +class Texture3D_OGL : public TextureBaseGL +{ +public: + Texture3D_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false ); + ~Texture3D_OGL(); + + virtual void UpdateData(IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData); + virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint ); + +private: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h new file mode 100644 index 00000000..0cc49ac1 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h @@ -0,0 +1,83 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BaseInterfacesGL.h" +#include "TextureGL.h" +#include "TextureBase.h" +#include "RenderDevice.h" +#include "GLObjectWrapper.h" +#include "TextureViewGLImpl.h" +#include "AsyncWritableResource.h" + +namespace Diligent +{ + +/// Base implementation of the Diligent::ITextureGL interface +class TextureBaseGL : public TextureBase<ITextureGL, TextureViewGLImpl>, public AsyncWritableResource +{ +public: + typedef TextureBase<ITextureGL, TextureViewGLImpl> TTextureBase; + + TextureBaseGL(class RenderDeviceGLImpl *pDeviceGL, const TextureDesc& BuffDesc, const TextureData &InitData = TextureData(), bool bIsDeviceInternal = false); + ~TextureBaseGL(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override; + + //virtual void CopyData(CTexture *pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size); + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; + virtual void Unmap( IDeviceContext *pContext )override; + + const GLObjectWrappers::GLTextureObj& GetGLHandle()const{ return m_GlTexture; } + GLenum GetBindTarget()const{return m_BindTarget;} + GLenum GetGLTexFormat()const{ return m_GLTexFormat; } + + void TextureMemoryBarrier( Uint32 RequiredBarriers, class GLContextState &GLContextState); + + virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint) = 0; + + virtual void CopyData(IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ)override; + +protected: + virtual void CreateViewInternal( const struct TextureViewDesc &ViewDesc, class ITextureView **ppView, bool bIsDefaultView )override; + void SetDefaultGLParameters(); + + GLObjectWrappers::GLTextureObj m_GlTexture; + GLenum m_BindTarget; + GLenum m_GLTexFormat; + //Uint32 m_uiMapTarget; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h new file mode 100644 index 00000000..4284eaaf --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h @@ -0,0 +1,60 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BaseInterfacesGL.h" +#include "TextureViewGL.h" +#include "TextureViewBase.h" +#include "RenderDevice.h" +#include "GLObjectWrapper.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::ITextureViewGL interface +class TextureViewGLImpl : public TextureViewBase<ITextureViewGL> +{ +public: + typedef TextureViewBase<ITextureViewGL> TTextureViewBase; + + TextureViewGLImpl( class IRenderDevice *pDevice, + const struct TextureViewDesc& ViewDesc, + class TextureBaseGL *pTexture, + bool bCreateGLViewTex, + bool bIsDefaultView ); + ~TextureViewGLImpl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + const GLObjectWrappers::GLTextureObj& GetHandle(); + GLenum GetBindTarget(); + + void GenerateMips( IDeviceContext *pContext )override; + +protected: + GLObjectWrappers::GLTextureObj m_ViewTexGLHandle; + GLenum m_ViewTexBindTarget; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/VAOCache.h b/Graphics/GraphicsEngineOpenGL/include/VAOCache.h new file mode 100644 index 00000000..2604fbcc --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/VAOCache.h @@ -0,0 +1,103 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "GraphicsTypes.h" +#include "Buffer.h" +#include "VertexDescription.h" +#include "LockHelper.h" +#include "HashUtils.h" +#include "DeviceContextBase.h" +#include "BaseInterfacesGL.h" + +namespace Diligent +{ + +class VAOCache +{ +public: + VAOCache(); + ~VAOCache(); + + const GLObjectWrappers::GLVertexArrayObj& GetVAO( IVertexDescription &VertexDesc, + IBuffer *pIndexBuffer, + vector< VertexStreamInfo > &VertexStreams, + class GLContextState &GLContextState); + void OnDestroyBuffer(IBuffer *pBuffer); + void OnDestroyVertexDesc(IVertexDescription *pVertexDesc); + +private: + // This structure is used as the key to find VAO + struct VAOCacheKey + { + // Note that the the pointers are used for ordering only + // They are not used to access the objects + IVertexDescription* pVertexDesc; + IBuffer* pIndexBuffer; + struct StreamAttribs + { + IBuffer* pBuffer; + Uint32 Stride; + Uint32 Offset; + }Streams[MaxBufferSlots]; + + bool operator == (const VAOCacheKey &Key)const + { + return (pVertexDesc == Key.pVertexDesc) && + (pIndexBuffer == Key.pIndexBuffer) && + (memcmp(Streams, Key.Streams, sizeof(Streams)) == 0); + } + }; + + struct VAOCacheKeyHashFunc + { + std::size_t operator() ( const VAOCacheKey& Key )const + { + std::size_t Seed = 0; + HashCombine(Seed, Key.pVertexDesc); + if(Key.pIndexBuffer) + HashCombine(Seed, Key.pIndexBuffer); + for(int iStream = 0; iStream < _countof(Key.Streams); ++iStream ) + { + auto &CurrStream = Key.Streams[iStream]; + if( CurrStream.pBuffer ) + { + HashCombine(Seed, CurrStream.pBuffer); + HashCombine(Seed, CurrStream.Offset); + HashCombine(Seed, CurrStream.Stride); + } + } + return Seed; + } + }; + + + friend class RenderDeviceGLImpl; + ThreadingTools::LockFlag m_CacheLockFlag; + std::unordered_map<VAOCacheKey, GLObjectWrappers::GLVertexArrayObj, VAOCacheKeyHashFunc> m_Cache; + std::unordered_multimap<IVertexDescription*, VAOCacheKey> m_VertexDescToKey; + std::unordered_multimap<IBuffer*, VAOCacheKey> m_BuffToKey; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/VertexDescGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/VertexDescGLImpl.h new file mode 100644 index 00000000..1953e044 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/VertexDescGLImpl.h @@ -0,0 +1,50 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BaseInterfacesGL.h" +#include "VertexDescriptionGL.h" +#include "VertexDescriptionBase.h" +#include "BaseInterfacesGL.h" +#include "RenderDevice.h" + +namespace Diligent +{ + +/// Implementation of the Diligent::IVertexDescriptionGL interface +class VertexDescGLImpl : public VertexDescriptionBase<IVertexDescriptionGL> +{ +public: + typedef VertexDescriptionBase<IVertexDescriptionGL> TVertexDescriptionBase; + + VertexDescGLImpl( class RenderDeviceGLImpl *pDeviceGL, const LayoutDesc &LayoutDesc, bool bIsDeviceInternal = false ); + ~VertexDescGLImpl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + +private: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/pch.h b/Graphics/GraphicsEngineOpenGL/include/pch.h new file mode 100644 index 00000000..e4530e99 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/pch.h @@ -0,0 +1,96 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include <vector> + +#include <map> +#include <unordered_map> +#include <unordered_set> +#include <algorithm> + +// Must be defined to use static version of glew +#ifdef _WINDOWS + #define GLEW_STATIC + #include "glew.h" + // Glew includes <windows.h> + #define NOMINMAX + #include "wglew.h" + #include <GL/GL.h> +#endif + + +#ifdef ANDROID +#ifndef USE_GL3_STUB + #define USE_GL3_STUB 0 +#endif + #if USE_GL3_STUB + #include "gl3stub.h" + #include <GLES2/gl2platform.h> + #else + #include <GLES3/gl3.h> + #include <GLES3/gl3platform.h> + #endif +#endif + +#include "Errors.h" + +#ifdef ANDROID + // GLStubs must be included after GLFeatures! + #include "GLStubs.h" +#endif + +#include "PlatformDefinitions.h" +#include "RefCntAutoPtr.h" +#include "DebugUtilities.h" +#include "GLObjectWrapper.h" +#include "DebugUtilities.h" +#include "ValidatedCast.h" +#include "RenderDevice.h" +#include "BaseInterfacesGL.h" + +using namespace Diligent; +using namespace std; + +#define CHECK_GL_ERROR(...)\ +{ \ + auto err = glGetError(); \ + if( err != GL_NO_ERROR ) \ + { \ + LogError<false>(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nGL Error Code: ", err); \ + UNEXPECTED("Error"); \ + } \ +} + +#define CHECK_GL_ERROR_AND_THROW(...)\ +{ \ + auto err = glGetError(); \ + if( err != GL_NO_ERROR ) \ + LogError<true>(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nGL Error Code: ", err); \ +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h b/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h new file mode 100644 index 00000000..01c0996c --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h @@ -0,0 +1,48 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#ifdef ANDROID + #include "RenderDeviceGLES.h" + namespace Diligent + { + static const Diligent::INTERFACE_ID IID_GLDeviceBaseInterface = IID_RenderDeviceGLES; + typedef IRenderDeviceGLES IGLDeviceBaseInterface; + } +#endif + +#ifdef _WINDOWS + #include "RenderDeviceGL.h" + namespace Diligent + { + static const Diligent::INTERFACE_ID IID_GLDeviceBaseInterface = IID_RenderDeviceGL; + typedef IRenderDeviceGL IGLDeviceBaseInterface; + } +#endif + +#include "DeviceContextGL.h" +namespace Diligent +{ + typedef IDeviceContextGL IGLDeviceContextBaseInterface; +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/interface/BlendStateGL.h b/Graphics/GraphicsEngineOpenGL/interface/BlendStateGL.h new file mode 100644 index 00000000..8923adf5 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/BlendStateGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBlendStateGL interface + +#include "BlendState.h" + +namespace Diligent +{ + +// {B543F4DC-000F-4EE6-AC06-E6642BBC3560} +static const Diligent::INTERFACE_ID IID_BlendStateGL = +{ 0xb543f4dc, 0xf, 0x4ee6, { 0xac, 0x6, 0xe6, 0x64, 0x2b, 0xbc, 0x35, 0x60 } }; + +/// Interface to the blend state object implemented in OpenGL +class IBlendStateGL : public Diligent::IBlendState +{ +public: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h b/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h new file mode 100644 index 00000000..33ed7c2b --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBufferGL interface + +#include "Buffer.h" + +namespace Diligent +{ + +// {08DF7319-F425-4EC7-8D2B-1B3FC0BDDBB4} +static const Diligent::INTERFACE_ID IID_BufferGL = +{ 0x8df7319, 0xf425, 0x4ec7, { 0x8d, 0x2b, 0x1b, 0x3f, 0xc0, 0xbd, 0xdb, 0xb4 } }; + +/// Interface to the buffer object implemented in OpenGL +class IBufferGL : public Diligent::IBuffer +{ +public: + //const GLObjectWrappers::GLBufferObj& GetGLBufferHandle() +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h b/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h new file mode 100644 index 00000000..3124a545 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBufferViewGL interface + +#include "BufferView.h" + +namespace Diligent +{ + +// {927A865B-3CEB-4743-9A22-2A1397A73E6D} +static const Diligent::INTERFACE_ID IID_BufferViewGL = +{ 0x927a865b, 0x3ceb, 0x4743, { 0x9a, 0x22, 0x2a, 0x13, 0x97, 0xa7, 0x3e, 0x6d } }; + +/// Interface to the buffer view object implemented in OpenGL +class IBufferViewGL : public Diligent::IBufferView +{ +public: + //const GLObjectWrappers::GLTextureObj& GetTexBufferHandle(){ return m_GLTexBuffer; } +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/DepthStencilStateGL.h b/Graphics/GraphicsEngineOpenGL/interface/DepthStencilStateGL.h new file mode 100644 index 00000000..70f568e5 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/DepthStencilStateGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IDepthStencilStateGL interface + +#include "DepthStencilState.h" + +namespace Diligent +{ + +// {96946955-33A3-46CA-BB83-207332AFB2A9} +static const Diligent::INTERFACE_ID IID_DepthStencilStateGL = +{ 0x96946955, 0x33a3, 0x46ca, { 0xbb, 0x83, 0x20, 0x73, 0x32, 0xaf, 0xb2, 0xa9 } }; + +/// Interface to the depth stencil state object implemented in OpenGL +class IDepthStencilStateGL : public Diligent::IDepthStencilState +{ +public: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h new file mode 100644 index 00000000..12f6f01a --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IDeviceContextGL interface + +#include "DeviceContext.h" + +namespace Diligent +{ + +// {3464FDF1-C548-4935-96C3-B454C9DF6F6A} +static const Diligent::INTERFACE_ID IID_DeviceContextGL = +{ 0x3464fdf1, 0xc548, 0x4935, { 0x96, 0xc3, 0xb4, 0x54, 0xc9, 0xdf, 0x6f, 0x6a } }; + +/// Interface to the device context object implemented in OpenGL +class IDeviceContextGL : public Diligent::IDeviceContext +{ +public: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/RasterizerStateGL.h b/Graphics/GraphicsEngineOpenGL/interface/RasterizerStateGL.h new file mode 100644 index 00000000..685dff08 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/RasterizerStateGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRasterizerStateGL interface + +#include "RasterizerState.h" + +namespace Diligent +{ + +// {B546E86A-E68D-4FC5-A7DC-04F8151941D2} +static const Diligent::INTERFACE_ID IID_RasterizerStateGL = +{ 0xb546e86a, 0xe68d, 0x4fc5, { 0xa7, 0xdc, 0x4, 0xf8, 0x15, 0x19, 0x41, 0xd2 } }; + +/// Interface to the rasterizer state object implemented in OpenGL +class IRasterizerStateGL : public Diligent::IRasterizerState +{ +public: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h new file mode 100644 index 00000000..59654ce2 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h @@ -0,0 +1,106 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "RenderDevice.h" +#include "SwapChain.h" + +#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_WINDOWS_STORE) + +# define API_QUALIFIER + +#elif defined(PLATFORM_ANDROID) + +# ifdef ENGINE_DLL +# ifdef BUILDING_DLL + // https://gcc.gnu.org/wiki/Visibility +# define API_QUALIFIER __attribute__((visibility("default"))) +# else +# define API_QUALIFIER __attribute__((visibility("default"))) +# endif +# else +# define API_QUALIFIER +# endif + +#endif + + +extern "C" +{ + +#if defined(ENGINE_DLL) && (defined(PLATFORM_WINDOWS) || defined(PLATFORM_WINDOWS_STORE)) + + typedef void (*CreateDeviceAndSwapChainGLType)( const Diligent::EngineCreationAttribs& CreationAttribs, + Diligent::IRenderDevice **ppDevice, + Diligent::IDeviceContext **ppImmediateContext, + const Diligent::SwapChainDesc& SwapChainDesc, + void *pNativeWndHandle, + Diligent::ISwapChain **ppSwapChain ); + + static void LoadGraphicsEngineOpenGL(CreateDeviceAndSwapChainGLType &CreateDeviceFunc) + { + CreateDeviceFunc = nullptr; + std::string LibName = "GraphicsEngineOpenGL_"; + +#if _WIN64 + LibName += "64"; +#else + LibName += "32"; +#endif + +#ifdef _DEBUG + LibName += "d"; +#else + LibName += "r"; +#endif + + LibName += ".dll"; + auto hModule = LoadLibraryA( LibName.c_str() ); + if( hModule == NULL ) + { + LOG_ERROR_MESSAGE( "Failed to load ", LibName, " library." ); + return; + } + + CreateDeviceFunc = reinterpret_cast<CreateDeviceAndSwapChainGLType>( GetProcAddress(hModule, "CreateDeviceAndSwapChainGL") ); + if( CreateDeviceFunc == NULL ) + { + LOG_ERROR_MESSAGE( "Failed to load CreateDeviceAndSwapChainGL() from ", LibName, " library." ); + FreeLibrary( hModule ); + return; + } + } + +#else + + // Do not forget to call System.loadLibrary("GraphicsEngineOpenGL") in Java on Android! + API_QUALIFIER + void CreateDeviceAndSwapChainGL( const Diligent::EngineCreationAttribs& CreationAttribs, + Diligent::IRenderDevice **ppDevice, + Diligent::IDeviceContext **ppImmediateContext, + const Diligent::SwapChainDesc& SwapChainDesc, + void *pNativeWndHandle, + Diligent::ISwapChain **ppSwapChain ); +#endif +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h new file mode 100644 index 00000000..6413c7e5 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h @@ -0,0 +1,46 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRenderDeviceGL interface + +#include "RenderDevice.h" + +/// Namespace for the OpenGL implementation of the graphics engine +namespace Diligent +{ + +// {B4B395B9-AC99-4E8A-B7E1-9DCA0D485618} +static const Diligent::INTERFACE_ID IID_RenderDeviceGL = +{ 0xb4b395b9, 0xac99, 0x4e8a, { 0xb7, 0xe1, 0x9d, 0xca, 0xd, 0x48, 0x56, 0x18 } }; + +/// Interface to the render device object implemented in OpenGL +class IRenderDeviceGL : public IRenderDevice +{ +public: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h new file mode 100644 index 00000000..97c82301 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h @@ -0,0 +1,51 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRenderDeviceGLES interface + +#include "RenderDevice.h" +#include <android\native_window.h> +#include <EGL/egl.h> + +namespace Diligent +{ + +// {F705A0D9-2023-4DE1-8B3C-C56E4CEB8DB7} +static const Diligent::INTERFACE_ID IID_RenderDeviceGLES = +{ 0xf705a0d9, 0x2023, 0x4de1, { 0x8b, 0x3c, 0xc5, 0x6e, 0x4c, 0xeb, 0x8d, 0xb7 } }; + +/// Interface to the render device object implemented in OpenGLES +class IRenderDeviceGLES : public Diligent::IRenderDevice +{ +public: + virtual bool Invalidate() = 0; + + virtual void Suspend() = 0; + + virtual EGLint Resume( ANativeWindow* window ) = 0; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h b/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h new file mode 100644 index 00000000..572cd2c2 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ISamplerGL interface + +#include "Sampler.h" + +namespace Diligent +{ + +// {3E9EB89E-E955-447A-9D13-92C10541F727} +static const Diligent::INTERFACE_ID IID_SamplerGL = +{ 0x3e9eb89e, 0xe955, 0x447a, { 0x9d, 0x13, 0x92, 0xc1, 0x5, 0x41, 0xf7, 0x27 } }; + +/// Interface to the sampler object object implemented in OpenGL +class ISamplerGL : public Diligent::ISampler +{ +public: + //const GLObjectWrappers::GLSamplerObj& GetHandle(){ return m_GlSampler; } +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h b/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h new file mode 100644 index 00000000..c6a5cf40 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IShaderGL interface + +#include "Shader.h" + +namespace Diligent +{ + +// {2FF3C191-285B-4E6C-BD0B-D084DDEA6FCC} +static const Diligent::INTERFACE_ID IID_ShaderGL = +{ 0x2ff3c191, 0x285b, 0x4e6c, { 0xbd, 0xb, 0xd0, 0x84, 0xdd, 0xea, 0x6f, 0xcc } }; + +/// Interface to the shader object implemented in OpenGL +class IShaderGL : public Diligent::IShader +{ +public: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h b/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h new file mode 100644 index 00000000..240586ac --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h @@ -0,0 +1,44 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ISwapChainGL interface + +#include "SwapChain.h" + +namespace Diligent +{ + +// {F457BD7C-E725-4D3E-8607-A1F9BAE329EB} +static const Diligent::INTERFACE_ID IID_SwapChainGL = +{ 0xf457bd7c, 0xe725, 0x4d3e, { 0x86, 0x7, 0xa1, 0xf9, 0xba, 0xe3, 0x29, 0xeb } }; + +/// Interface to the swap chain object implemented in OpenGL +class ISwapChainGL : public Diligent::ISwapChain +{ +public: +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h b/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h new file mode 100644 index 00000000..7424b4d0 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h @@ -0,0 +1,47 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ITextureGL interface + +#include "Texture.h" + +namespace Diligent +{ + +// {D7BC9FF0-28F0-4636-9732-710C204D1D63} +static const Diligent::INTERFACE_ID IID_TextureGL = +{ 0xd7bc9ff0, 0x28f0, 0x4636, { 0x97, 0x32, 0x71, 0xc, 0x20, 0x4d, 0x1d, 0x63 } }; + +/// Interface to the texture object implemented in OpenGL +class ITextureGL : public Diligent::ITexture +{ +public: + //const GLObjectWrappers::GLTextureObj& GetGLHandle()const{ return m_GlTexture; } + //GLenum GetBindTarget()const{return m_BindTarget;} + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h b/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h new file mode 100644 index 00000000..15389154 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h @@ -0,0 +1,46 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ITextureViewGL interface + +#include "TextureView.h" + +namespace Diligent +{ + +// {15F93272-6135-414F-AB10-53FF9A5004AD} +static const Diligent::INTERFACE_ID IID_TextureViewGL = +{ 0x15f93272, 0x6135, 0x414f, { 0xab, 0x10, 0x53, 0xff, 0x9a, 0x50, 0x4, 0xad } }; + +/// Interface to the texture view object implemented in OpenGL +class ITextureViewGL : public ITextureView +{ +public: + //const GLObjectWrappers::GLTextureObj& GetHandle(); + //GLenum GetBindTarget(); +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/VertexDescriptionGL.h b/Graphics/GraphicsEngineOpenGL/interface/VertexDescriptionGL.h new file mode 100644 index 00000000..1a785e9b --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/interface/VertexDescriptionGL.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IVertexDescriptionGL interface + +#include "VertexDescription.h" + +namespace Diligent +{ + +// {4CBEE16A-7C22-4F10-8CB5-6D4E393638C7} +static const Diligent::INTERFACE_ID IID_VertexDescriptionGL = +{ 0x4cbee16a, 0x7c22, 0x4f10, { 0x8c, 0xb5, 0x6d, 0x4e, 0x39, 0x36, 0x38, 0xc7 } }; + +/// Interface to the vertex description object implemented in OpenGL +class IVertexDescriptionGL : public Diligent::IVertexDescription +{ +public: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/BlendStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BlendStateGLImpl.cpp new file mode 100644 index 00000000..fd0f1734 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/BlendStateGLImpl.cpp @@ -0,0 +1,42 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "BlendStateGLImpl.h" +#include "RenderDeviceGLImpl.h" + +namespace Diligent +{ + +BlendStateGLImpl::BlendStateGLImpl(class IRenderDevice *pDeviceGL, const BlendStateDesc& BlendStateDesc, bool bIsDeviceInternal) : + TBlendStateBase(pDeviceGL, BlendStateDesc, bIsDeviceInternal) +{ +} + +BlendStateGLImpl::~BlendStateGLImpl() +{ +} + +IMPLEMENT_QUERY_INTERFACE( BlendStateGLImpl, IID_BlendStateGL, TBlendStateBase ) + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp new file mode 100644 index 00000000..27bce444 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp @@ -0,0 +1,311 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "BufferGLImpl.h" +#include "RenderDeviceGLImpl.h" +#include "GLTypeConversions.h" +#include "BufferViewGLImpl.h" +#include "DeviceContextGLImpl.h" + +namespace Diligent +{ + +BufferGLImpl::BufferGLImpl(class RenderDeviceGLImpl *pDeviceGL, const BufferDesc& BuffDesc, const BufferData &BuffData /*= BufferData()*/, bool IsDeviceInternal /*= false*/) : + TBufferBase( pDeviceGL, BuffDesc, IsDeviceInternal ), + m_GlBuffer(true), // Create buffer immediately + m_uiMapTarget(0), + m_GLUsageHint(0), + m_bUseMapWriteDiscardBugWA(False) +{ + // On Intel GPUs, mapping buffer with GL_MAP_UNSYNCHRONIZED_BIT does not + // work as expected. To workaround this issue, use glBufferData() to + // orphan previous buffer storage https://www.opengl.org/wiki/Buffer_Object_Streaming + if( pDeviceGL->GetGPUInfo().Vendor == GPU_VENDOR::INTEL ) + m_bUseMapWriteDiscardBugWA = True; + + if( BuffDesc.Usage == USAGE_STATIC && BuffData.pData == nullptr ) + LOG_ERROR_AND_THROW("Static buffer must be initialized with data at creation time"); + + // TODO: find out if it affects performance if the buffer is originally bound to one target + // and then bound to another (such as first to GL_ARRAY_BUFFER and then to GL_UNIFORM_BUFFER) + glBindBuffer(GL_ARRAY_BUFFER, m_GlBuffer); + VERIFY(BuffData.pData == nullptr || BuffData.DataSize >= BuffDesc.uiSizeInBytes, "Data pointer is null or data size is not consistent with buffer size" ); + GLsizeiptr DataSize = BuffDesc.uiSizeInBytes; + const GLvoid *pData = nullptr; + if( BuffData.pData && BuffData.DataSize >= BuffDesc.uiSizeInBytes ) + { + pData = BuffData.pData; + DataSize = BuffData.DataSize; + } + // Create and initialize a buffer object's data store + + // Target must be one of GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, + // GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TEXTURE_BUFFER, + // GL_TRANSFORM_FEEDBACK_BUFFER, or GL_UNIFORM_BUFFER. + + // Usage must be one of GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, + // GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY. + + //The frequency of access may be one of these: + // + //STREAM + // The data store contents will be modified once and used at most a few times. + // + //STATIC + // The data store contents will be modified once and used many times. + // + //DYNAMIC + // The data store contents will be modified repeatedly and used many times. + // + + //The nature of access may be one of these: + // + //DRAW + // The data store contents are modified by the application, and used as the source for GL + // drawing and image specification commands. + // + //READ + // The data store contents are modified by reading data from the GL, and used to return that + // data when queried by the application. + // + //COPY + // The data store contents are modified by reading data from the GL, and used as the source + // for GL drawing and image specification commands. + + // See also http://www.informit.com/articles/article.aspx?p=2033340&seqNum=2 + + m_GLUsageHint = UsageToGLUsage(BuffDesc.Usage); + // All buffer bind targets (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc.) relate to the same + // kind of objects. As a result they are all equivalent from a transfer point of view. + glBufferData(GL_ARRAY_BUFFER, DataSize, pData, m_GLUsageHint); + CHECK_GL_ERROR_AND_THROW("glBufferData() failed"); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +BufferGLImpl::~BufferGLImpl() +{ + static_cast<RenderDeviceGLImpl*>( static_cast<IRenderDevice*>( GetDevice() ) )->m_VAOCache.OnDestroyBuffer(this); +} + +IMPLEMENT_QUERY_INTERFACE( BufferGLImpl, IID_BufferGL, TBufferBase ) + +void BufferGLImpl :: UpdateData(IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData) +{ + TBufferBase::UpdateData( pContext, Offset, Size, pData ); + + CHECK_DYNAMIC_TYPE( DeviceContextGLImpl, pContext ); + auto *pDeviceContextGL = static_cast<DeviceContextGLImpl*>(pContext); + + BufferMemoryBarrier( + GL_BUFFER_UPDATE_BARRIER_BIT,// Reads or writes to buffer objects via any OpenGL API functions that allow + // modifying their contents will reflect data written by shaders prior to the barrier. + // Additionally, writes via these commands issued after the barrier will wait on + // the completion of any shader writes to the same memory initiated prior to the barrier. + pDeviceContextGL->GetContextState()); + + glBindBuffer(GL_ARRAY_BUFFER, m_GlBuffer); + // All buffer bind targets (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc.) relate to the same + // kind of objects. As a result they are all equivalent from a transfer point of view. + glBufferSubData(GL_ARRAY_BUFFER, Offset, Size, pData); + CHECK_GL_ERROR("glBufferSubData() failed"); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + + +void BufferGLImpl :: CopyData(IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size) +{ + TBufferBase::CopyData( pContext, pSrcBuffer, SrcOffset, DstOffset, Size ); + + CHECK_DYNAMIC_TYPE( DeviceContextGLImpl, pContext ); + auto *pDeviceContextGL = static_cast<DeviceContextGLImpl*>(pContext); + + auto *pSrcBufferGL = static_cast<BufferGLImpl*>( pSrcBuffer ); + + BufferMemoryBarrier( + GL_BUFFER_UPDATE_BARRIER_BIT,// Reads or writes to buffer objects via any OpenGL API functions that allow + // modifying their contents will reflect data written by shaders prior to the barrier. + // Additionally, writes via these commands issued after the barrier will wait on + // the completion of any shader writes to the same memory initiated prior to the barrier. + pDeviceContextGL->GetContextState()); + pSrcBufferGL->BufferMemoryBarrier( GL_BUFFER_UPDATE_BARRIER_BIT, pDeviceContextGL->GetContextState() ); + + // Whilst glCopyBufferSubData() can be used to copy data between buffers bound to any two targets, + // the targets GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER are provided specifically for this purpose. + // Neither target is used for anything else by OpenGL, and so you can safely bind buffers to them for + // the purposes of copying or staging data without disturbing OpenGL state or needing to keep track of + // what was bound to the target before your copy. + glBindBuffer(GL_COPY_WRITE_BUFFER, m_GlBuffer); + glBindBuffer(GL_COPY_READ_BUFFER, pSrcBufferGL->m_GlBuffer); + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, SrcOffset, DstOffset, Size); + CHECK_GL_ERROR("glCopyBufferSubData() failed"); + glBindBuffer(GL_COPY_READ_BUFFER, 0); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); +} + +void BufferGLImpl :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) +{ + TBufferBase::Map( pContext, MapType, MapFlags, pMappedData ); + VERIFY( m_uiMapTarget == 0, "Buffer is already mapped"); + + CHECK_DYNAMIC_TYPE( DeviceContextGLImpl, pContext ); + auto *pDeviceContextGL = static_cast<DeviceContextGLImpl*>(pContext); + + BufferMemoryBarrier( + GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT,// Access by the client to persistent mapped regions of buffer + // objects will reflect data written by shaders prior to the barrier. + // Note that this may cause additional synchronization operations. + pDeviceContextGL->GetContextState()); + m_uiMapTarget = ( MapType == MAP_READ ) ? GL_COPY_READ_BUFFER : GL_COPY_WRITE_BUFFER; + glBindBuffer(m_uiMapTarget, m_GlBuffer); + + // !!!WARNING!!! GL_MAP_UNSYNCHRONIZED_BIT is not the same thing as MAP_FLAG_DO_NOT_WAIT. + // If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize operations + // on the buffer. This does not mean that map will fail if the buffer still in use. It is thus + // what WRITE_NO_OVERWRITE does + + GLbitfield Access = 0; + switch(MapType) + { + case MAP_READ: + Access |= GL_MAP_READ_BIT; + break; + + case MAP_WRITE: + Access |= GL_MAP_WRITE_BIT; + break; + + case MAP_READ_WRITE: + Access |= GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + break; + + case MAP_WRITE_DISCARD: + + if( m_bUseMapWriteDiscardBugWA ) + { + // On Intel GPU, mapping buffer with GL_MAP_UNSYNCHRONIZED_BIT does not + // work as expected. To workaround this issue, use glBufferData() to + // orphan previous buffer storage https://www.opengl.org/wiki/Buffer_Object_Streaming + + // It is important to specify the exact same buffer size and usage to allow the + // implementation to simply reallocate storage for that buffer object under-the-hood. + // Since NULL is passed, if there wasn't a need for synchronization to begin with, + // this can be reduced to a no-op. + glBufferData(m_uiMapTarget, m_Desc.uiSizeInBytes, nullptr, m_GLUsageHint); + CHECK_GL_ERROR("glBufferData() failed"); + Access |= GL_MAP_WRITE_BIT; + } + else + { + // Use GL_MAP_INVALIDATE_BUFFER_BIT flag to discard previous buffer contents + + // If GL_MAP_INVALIDATE_BUFFER_BIT is specified, the entire contents of the buffer may + // be discarded and considered invalid, regardless of the specified range. Any data + // lying outside the mapped range of the buffer object becomes undefined,as does any + // data within the range but not subsequently written by the application.This flag may + // not be used with GL_MAP_READ_BIT. + + Access |= GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_WRITE_BIT; + } + break; + + case MAP_WRITE_NO_OVERWRITE: + // If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize + // operations on the buffer. + Access |= GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + break; + + default: UNEXPECTED( "Unknown map type" ); + } + + pMappedData = glMapBufferRange(m_uiMapTarget, 0, m_Desc.uiSizeInBytes, Access); + CHECK_GL_ERROR("glMapBufferRange() failed"); + VERIFY( pMappedData, "Map failed" ); + glBindBuffer(m_uiMapTarget, 0); +} + +void BufferGLImpl::Unmap( IDeviceContext *pContext ) +{ + TBufferBase::Unmap(pContext); + + glBindBuffer(m_uiMapTarget, m_GlBuffer); + auto Result = glUnmapBuffer(m_uiMapTarget); + // glUnmapBuffer() returns TRUE unless data values in the buffer’s data store have + // become corrupted during the period that the buffer was mapped. Such corruption + // can be the result of a screen resolution change or other window system - dependent + // event that causes system heaps such as those for high - performance graphics memory + // to be discarded. GL implementations must guarantee that such corruption can + // occur only during the periods that a buffer’s data store is mapped. If such corruption + // has occurred, glUnmapBuffer() returns FALSE, and the contents of the buffer’s + // data store become undefined. + VERIFY( Result != GL_FALSE, "Failed to unmap buffer. The data may have been corrupted" ); + glBindBuffer(m_uiMapTarget, 0); + m_uiMapTarget = 0; +} + +void BufferGLImpl::BufferMemoryBarrier( Uint32 RequiredBarriers, GLContextState &GLContextState ) +{ + const Uint32 BufferBarriers = + GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | + GL_ELEMENT_ARRAY_BARRIER_BIT | + GL_UNIFORM_BARRIER_BIT | + GL_COMMAND_BARRIER_BIT | + GL_BUFFER_UPDATE_BARRIER_BIT | + GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT | + GL_SHADER_STORAGE_BARRIER_BIT | + GL_TEXTURE_FETCH_BARRIER_BIT; + VERIFY( (RequiredBarriers & BufferBarriers) !=0, "At least one buffer memory barrier flag should be set" ); + VERIFY( (RequiredBarriers & ~BufferBarriers) == 0, "Inappropriate buffer memory barrier flag" ); + + GLContextState.EnsureMemoryBarrier( RequiredBarriers, this ); +} + +void BufferGLImpl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, class IBufferView **ppView, bool bIsDefaultView ) +{ + VERIFY( ppView != nullptr, "Buffer view pointer address is null" ); + if( !ppView )return; + VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + + *ppView = nullptr; + + try + { + auto ViewDesc = OrigViewDesc; + CorrectBufferViewDesc( ViewDesc ); + + auto pContext = ValidatedCast<RenderDeviceGLImpl>( GetDevice() )->GetImmediateContext(); + VERIFY( pContext, "Immediate context has been released" ); + *ppView = new BufferViewGLImpl( GetDevice(), pContext, ViewDesc, this, bIsDefaultView ); + + if( !bIsDefaultView ) + (*ppView)->AddRef(); + } + catch( const std::runtime_error & ) + { + const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType); + LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name ? m_Desc.Name : "", "\"" ) + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp new file mode 100644 index 00000000..6c185749 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp @@ -0,0 +1,60 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "BufferViewGLImpl.h" +#include "BufferGLImpl.h" +#include "GLTypeConversions.h" + +namespace Diligent +{ + BufferViewGLImpl::BufferViewGLImpl( IRenderDevice *pDevice, + IDeviceContext *pContext, + const BufferViewDesc& ViewDesc, + BufferGLImpl* pBuffer, + bool bIsDefaultView) : + TBuffViewBase(pDevice, ViewDesc, pBuffer, bIsDefaultView ), + m_GLTexBuffer(false) + { + if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE ) + { + auto *pContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); + auto &ContextState = pContextGL->GetContextState(); + + m_GLTexBuffer.Create(); + ContextState.BindTexture(-1, GL_TEXTURE_BUFFER, m_GLTexBuffer ); + + const auto &BuffFmt = pBuffer->GetDesc().Format; + auto GLFormat = TypeToGLTexFormat( BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized ); + glTexBuffer( GL_TEXTURE_BUFFER, GLFormat, pBuffer->GetGLBufferHandle() ); + CHECK_GL_ERROR_AND_THROW( "Failed to create texture buffer" ); + + ContextState.BindTexture(-1, GL_TEXTURE_BUFFER, GLObjectWrappers::GLTextureObj(false) ); + } + } + + IMPLEMENT_QUERY_INTERFACE( BufferViewGLImpl, IID_BufferViewGL, TBuffViewBase ) +} diff --git a/Graphics/GraphicsEngineOpenGL/src/DLLMain.cpp b/Graphics/GraphicsEngineOpenGL/src/DLLMain.cpp new file mode 100644 index 00000000..373d1570 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/DLLMain.cpp @@ -0,0 +1,49 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) +{ + switch( ul_reason_for_call ) + { + case DLL_PROCESS_ATTACH: + #if defined(_DEBUG) || defined(DEBUG) + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); + #endif + break; + + case DLL_THREAD_ATTACH: + break; + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/src/DSStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DSStateGLImpl.cpp new file mode 100644 index 00000000..1b9929b6 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/DSStateGLImpl.cpp @@ -0,0 +1,43 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "DSStateGLImpl.h" +#include "RenderDeviceGLImpl.h" + +namespace Diligent +{ + +DSStateGLImpl::DSStateGLImpl(class IRenderDevice *pDeviceGL, const DepthStencilStateDesc& DepthStencilStateDesc, bool bIsDeviceInternal) : + TDSStateBase(pDeviceGL, DepthStencilStateDesc, bIsDeviceInternal) +{ +} + +DSStateGLImpl::~DSStateGLImpl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( DSStateGLImpl, IID_DepthStencilStateGL, TDSStateBase ) + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp new file mode 100644 index 00000000..832a5eb8 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -0,0 +1,889 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "DeviceContextGLImpl.h" +#include "RenderDeviceGLImpl.h" +#include "GLTypeConversions.h" + +#include <iostream> +#include <fstream> +#include <string> + +#include "BufferGLImpl.h" +#include "VertexDescGLImpl.h" +#include "ShaderGLImpl.h" +#include "VAOCache.h" +#include "ProgramPipelineCache.h" +#include "Texture1D_OGL.h" +#include "Texture1DArray_OGL.h" +#include "Texture2D_OGL.h" +#include "Texture2DArray_OGL.h" +#include "Texture3D_OGL.h" +#include "SamplerGLImpl.h" +#include "GraphicsUtilities.h" +#include "BufferViewGLImpl.h" +#include "DSStateGLImpl.h" +#include "BlendStateGLImpl.h" +#include "RasterizerStateGLImpl.h" + +using namespace std; + +namespace Diligent +{ + DeviceContextGLImpl::DeviceContextGLImpl( class RenderDeviceGLImpl *pDeviceGL ) : + TDeviceContextBase(pDeviceGL), + m_ContextState(pDeviceGL) + { + m_BoundWritableTextures.reserve( 16 ); + m_BoundWritableBuffers.reserve( 16 ); + + // When GL_FRAMEBUFFER_SRGB is enabled, and if the destination image is in the sRGB colorspace + // then OpenGL will assume the shader's output is in the linear RGB colorspace. It will therefore + // convert the output from linear RGB to sRGB. + // Any writes to images that are not in the sRGB format should not be affected. + // Thus this setting should be just set once and left that way + glEnable(GL_FRAMEBUFFER_SRGB); + if( glGetError() != GL_NO_ERROR ) + LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); + } + + IMPLEMENT_QUERY_INTERFACE( DeviceContextGLImpl, IID_DeviceContextGL, TDeviceContextBase ) + + + void DeviceContextGLImpl::SetShaders( IShader **ppShaders, Uint32 NumShadersToSet ) + { + TDeviceContextBase::SetShaders( ppShaders, NumShadersToSet ); + + } + + void DeviceContextGLImpl::BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) + { + TDeviceContextBase::BindShaderResources( pResourceMapping, Flags ); + if( m_pDevice->GetDeviceCaps().bSeparableProgramSupported ) + { + for( auto it = m_pBoundShaders.begin(); it != m_pBoundShaders.end(); ++it ) + { + (*it)->BindResources( pResourceMapping, Flags ); + } + } + else + { + auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pDevice.RawPtr()); + auto &PipelineCache = pRenderDeviceGL->m_PipelineCache; + auto &PipelineOrProg = PipelineCache.GetProgramPipeline( m_pBoundShaders.data(), (Uint32)m_pBoundShaders.size() ); + if( PipelineOrProg.Program ) + PipelineOrProg.Program.BindResources( pResourceMapping, Flags ); + } + } + + void DeviceContextGLImpl::SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) + { + TDeviceContextBase::SetVertexBuffers( StartSlot, NumBuffersSet, ppBuffers, pStrides, pOffsets, Flags ); + + } + + void DeviceContextGLImpl::ClearState() + { + TDeviceContextBase::ClearState(); + + } + + void DeviceContextGLImpl::SetVertexDescription( IVertexDescription *pVertexDesc ) + { + TDeviceContextBase::SetVertexDescription( pVertexDesc ); + } + + void DeviceContextGLImpl::SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) + { + TDeviceContextBase::SetIndexBuffer( pIndexBuffer, ByteOffset ); + } + + void DeviceContextGLImpl::SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef ) + { + if( TDeviceContextBase::SetDepthStencilState( pDepthStencilState, StencilRef ) ) + { + CHECK_DYNAMIC_TYPE( DSStateGLImpl, pDepthStencilState ); + auto *pDSSGL = static_cast<DSStateGLImpl*>(pDepthStencilState); + const auto &DSSDesc = pDepthStencilState->GetDesc(); + + m_ContextState.EnableDepthTest( DSSDesc.DepthEnable ); + m_ContextState.EnableDepthWrites( DSSDesc.DepthWriteEnable ); + m_ContextState.SetDepthFunc( DSSDesc.DepthFunc ); + + m_ContextState.EnableStencilTest( DSSDesc.StencilEnable ); + + m_ContextState.SetStencilWriteMask( DSSDesc.StencilWriteMask ); + + { + const auto &FrontFace = DSSDesc.FrontFace; + m_ContextState.SetStencilFunc( GL_FRONT, FrontFace.StencilFunc, StencilRef, DSSDesc.StencilReadMask ); + m_ContextState.SetStencilOp( GL_FRONT, FrontFace.StencilFailOp, FrontFace.StencilDepthFailOp, FrontFace.StencilPassOp ); + } + + { + const auto &BackFace = DSSDesc.BackFace; + m_ContextState.SetStencilFunc( GL_BACK, BackFace.StencilFunc, StencilRef, DSSDesc.StencilReadMask ); + m_ContextState.SetStencilOp( GL_BACK, BackFace.StencilFailOp, BackFace.StencilDepthFailOp, BackFace.StencilPassOp ); + } + } + } + + void DeviceContextGLImpl::SetRasterizerState( IRasterizerState *pRasterizerState ) + { + if( TDeviceContextBase::SetRasterizerState( pRasterizerState ) ) + { + CHECK_DYNAMIC_TYPE( RasterizerStateGLImpl, pRasterizerState ); + auto *pRSGL = static_cast<RasterizerStateGLImpl*>(pRasterizerState); + const auto &RSDesc = pRasterizerState->GetDesc(); + + m_ContextState.SetFillMode(RSDesc.FillMode); + m_ContextState.SetCullMode(RSDesc.CullMode); + m_ContextState.SetFrontFace(RSDesc.FrontCounterClockwise); + m_ContextState.SetDepthBias( static_cast<Float32>( RSDesc.DepthBias ), RSDesc.SlopeScaledDepthBias ); + if( RSDesc.DepthBiasClamp != 0 ) + LOG_WARNING_MESSAGE( "Depth bias clamp is not supported on OpenGL" ); + m_ContextState.SetDepthClamp( RSDesc.DepthClipEnable ); + m_ContextState.EnableScissorTest( RSDesc.ScissorEnable ); + if( RSDesc.AntialiasedLineEnable ) + LOG_WARNING_MESSAGE( "Line antialiasing is not supported on OpenGL" ); + } + } + + + void DeviceContextGLImpl::SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask ) + { + if( TDeviceContextBase::SetBlendState( pBS, pBlendFactors, SampleMask ) ) + { + CHECK_DYNAMIC_TYPE( BlendStateGLImpl, pBS ); + auto *pBSGL = static_cast<BlendStateGLImpl*>(pBS); + const auto BSDsc = pBS->GetDesc(); + m_ContextState.SetBlendState(BSDsc, m_BlendFactors, SampleMask); + } + } + + void DeviceContextGLImpl::SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight ) + { + TDeviceContextBase::SetViewports( NumViewports, pViewports, RTWidth, RTHeight ); + + VERIFY( NumViewports == m_Viewports.size(), "Unexpected number of viewports" ); + if( NumViewports == 1 ) + { + const auto &vp = m_Viewports[0]; + // Note that OpenGL and DirectX use different origin of + // the viewport in window coordinates: + // + // DirectX (0,0) + // \ ____________ + // | | + // | | + // | | + // | | + // |____________| + // / + // OpenGL (0,0) + // + float BottomLeftY = static_cast<float>(RTHeight) - (vp.TopLeftY + vp.Height); + float BottomLeftX = vp.TopLeftX; + + Int32 x = static_cast<int>(BottomLeftX); + Int32 y = static_cast<int>(BottomLeftY); + Int32 w = static_cast<int>(vp.Width); + Int32 h = static_cast<int>(vp.Height); + if( static_cast<float>(x) == BottomLeftX && + static_cast<float>(y) == BottomLeftY && + static_cast<float>(w) == vp.Width && + static_cast<float>(h) == vp.Height ) + { + glViewport( x, y, w, h ); + } + else + { + glViewportIndexedf( 0, BottomLeftX, BottomLeftY, vp.Width, vp.Height ); + } + CHECK_GL_ERROR( "Failed to set viewport" ); + + glDepthRangef( vp.MinDepth, vp.MaxDepth ); + CHECK_GL_ERROR( "Failed to set depth range" ); + } + else + { + for( Uint32 i = 0; i < NumViewports; ++i ) + { + const auto &vp = m_Viewports[i]; + float BottomLeftY = static_cast<float>(RTHeight) - (vp.TopLeftY + vp.Height); + float BottomLeftX = vp.TopLeftX; + glViewportIndexedf( i, BottomLeftX, BottomLeftY, vp.Width, vp.Height ); + CHECK_GL_ERROR( "Failed to set viewport #", i ); + glDepthRangef( vp.MinDepth, vp.MaxDepth ); + CHECK_GL_ERROR( "Failed to set depth range for viewport #", i ); + } + } + } + + void DeviceContextGLImpl::SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight ) + { + TDeviceContextBase::SetScissorRects(NumRects, pRects, RTWidth, RTHeight); + + VERIFY( NumRects == m_ScissorRects.size(), "Unexpected number of scissor rects" ); + if( NumRects == 1 ) + { + const auto &Rect = m_ScissorRects[0]; + // Note that OpenGL and DirectX use different origin + // of the viewport in window coordinates: + // + // DirectX (0,0) + // \ ____________ + // | | + // | | + // | | + // | | + // |____________| + // / + // OpenGL (0,0) + // + auto glBottom = RTHeight - Rect.bottom; + + auto width = Rect.right - Rect.left; + auto height = Rect.bottom - Rect.top; + glScissor( Rect.left, glBottom, width, height ); + CHECK_GL_ERROR( "Failed to set scissor rect" ); + } + else + { + for( Uint32 sr = 0; sr < NumRects; ++sr ) + { + const auto &Rect = m_ScissorRects[sr]; + auto glBottom = RTHeight - Rect.bottom; + auto width = Rect.right - Rect.left; + auto height = Rect.bottom - Rect.top; + glScissorIndexed(sr, Rect.left, glBottom, width, height ); + CHECK_GL_ERROR( "Failed to set scissor rect #", sr ); + } + } + } + + void DeviceContextGLImpl::RebindRenderTargets() + { + Uint32 NumRenderTargets = static_cast<Uint32>( m_pBoundRenderTargets.size() ); + VERIFY( NumRenderTargets < MaxRenderTargets, "Too many render targets (", NumRenderTargets, ") are being set" ); + + NumRenderTargets = std::min( NumRenderTargets, MaxRenderTargets ); + ITextureView *pBoundRTVs[MaxRenderTargets] = {}; + for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + pBoundRTVs[rt] = m_pBoundRenderTargets[rt]; + + auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pDevice.RawPtr()); + auto &FBOCache = pRenderDeviceGL->m_FBOCache; + const auto& FBO = FBOCache.GetFBO( NumRenderTargets, pBoundRTVs, m_pBoundDepthStencil, m_ContextState ); + // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT + // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. + // Binding a new framebuffer will NOT affect the mask. + m_ContextState.BindFBO( FBO ); + + // Set the viewport to match the render target size + SetViewports(1, nullptr, 0, 0); + } + + void DeviceContextGLImpl::SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil ) + { + if( TDeviceContextBase::SetRenderTargets( NumRenderTargets, ppRenderTargets, pDepthStencil ) ) + RebindRenderTargets(); + } + + void DeviceContextGLImpl::BindProgramResources( Uint32 &NewMemoryBarriers ) + { + auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pDevice.RawPtr()); + auto &PipelineCache = pRenderDeviceGL->m_PipelineCache; + auto &PipelineOrProg = PipelineCache.GetProgramPipeline( m_pBoundShaders.data(), (Uint32)m_pBoundShaders.size() ); + + const auto &DeviceCaps = pRenderDeviceGL->GetDeviceCaps(); + GLuint Prog = PipelineOrProg.Program; + GLuint Pipeline = PipelineOrProg.Pipeline; + VERIFY( Prog ^ Pipeline, "Only one of program or pipeline can be specified" ); + if( !(Prog || Pipeline) ) + { + LOG_ERROR_MESSAGE( "No program/program pipeline is set for the draw call" ) + return; + } + auto ProgramPipelineSupported = DeviceCaps.bSeparableProgramSupported; + + // WARNING: glUseProgram() overrides glBindProgramPipeline(). That is, if you have a program in use and + // a program pipeline bound, all rendering will use the program that is in use, not the pipeline programs!!! + // So make sure that glUseProgram(0) has been called if pipeline is in use + m_ContextState.SetProgram( PipelineOrProg.Program ); + if( ProgramPipelineSupported ) + m_ContextState.SetPipeline( PipelineOrProg.Pipeline ); + + size_t NumPrograms = ProgramPipelineSupported ? m_pBoundShaders.size() : 1; + GLuint UniformBuffBindPoint = 0; + GLuint TextureIndex = 0; + m_BoundWritableTextures.clear(); + m_BoundWritableBuffers.clear(); + for( size_t ProgNum = 0; ProgNum < NumPrograms; ++ProgNum ) + { + auto *pShaderGL = static_cast<ShaderGLImpl*>(m_pBoundShaders[ProgNum].RawPtr()); + auto &GLProgramObj = ProgramPipelineSupported ? pShaderGL->m_GlProgObj : PipelineOrProg.Program; + +#ifdef VERIFY_RESOURCE_BINDINGS + GLProgramObj.dbgVerifyResourceBindings(); +#endif + + GLuint GLProgID = GLProgramObj; + auto &UniformBlocks = GLProgramObj.GetUniformBlocks(); + for( auto it = UniformBlocks.begin(); it != UniformBlocks.end(); ++it ) + { + auto& pResource = it->pResource; + if( pResource ) + { + CHECK_DYNAMIC_TYPE( BufferGLImpl, pResource.RawPtr() ); + auto *pBufferOGL = static_cast<BufferGLImpl*>(pResource.RawPtr()); + pBufferOGL->BufferMemoryBarrier( + GL_UNIFORM_BARRIER_BIT,// Shader uniforms sourced from buffer objects after the barrier + // will reflect data written by shaders prior to the barrier + m_ContextState); + + glBindBufferBase( GL_UNIFORM_BUFFER, UniformBuffBindPoint, pBufferOGL->m_GlBuffer ); + CHECK_GL_ERROR( "Failed to bind uniform buffer" ); + //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferOGL->m_GlBuffer, 0, pBufferOGL->GetDesc().uiSizeInBytes); + + glUniformBlockBinding( GLProgID, it->Index, UniformBuffBindPoint ); + CHECK_GL_ERROR( "glUniformBlockBinding() failed" ); + + ++UniformBuffBindPoint; + } + else + { +#define LOG_MISSING_BINDING(VarType, VarName) LOG_ERROR_MESSAGE( "No ", VarType, " is bound to \"", VarName, "\" variable in shader \"", pShaderGL->GetDesc().Name, "\"" ); + LOG_MISSING_BINDING("uniform buffer", it->Name) + } + } + + auto &Samplers = GLProgramObj.GetSamplers(); + for( auto it = Samplers.begin(); it != Samplers.end(); ++it ) + { + auto &pResource = it->pResource; + if( pResource ) + { + if( it->Type == GL_SAMPLER_BUFFER || + it->Type == GL_INT_SAMPLER_BUFFER || + it->Type == GL_UNSIGNED_INT_SAMPLER_BUFFER ) + { + CHECK_DYNAMIC_TYPE( BufferViewGLImpl, pResource.RawPtr() ); + auto *pBufViewOGL = static_cast<BufferViewGLImpl*>(pResource.RawPtr()); + auto *pBuffer = pBufViewOGL->GetBuffer(); + + m_ContextState.BindTexture( TextureIndex, GL_TEXTURE_BUFFER, pBufViewOGL->GetTexBufferHandle() ); + m_ContextState.BindSampler( TextureIndex, GLObjectWrappers::GLSamplerObj(false) ); // Use default texture sampling parameters + + CHECK_DYNAMIC_TYPE( BufferGLImpl, pBuffer ); + static_cast<BufferGLImpl*>(pBuffer)->BufferMemoryBarrier( + GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object + // memory via buffer textures, after the barrier will reflect data + // written by shaders prior to the barrier + m_ContextState); + } + else + { + CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pResource.RawPtr() ); + auto *pTexViewOGL = static_cast<TextureViewGLImpl*>(pResource.RawPtr()); + m_ContextState.BindTexture( TextureIndex, pTexViewOGL->GetBindTarget(), pTexViewOGL->GetHandle() ); + + auto *pTexture = pTexViewOGL->GetTexture(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); + static_cast<TextureBaseGL*>(pTexture)->TextureMemoryBarrier( + GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object + // memory via buffer textures, after the barrier will reflect data + // written by shaders prior to the barrier + m_ContextState); + + auto pSampler = pTexViewOGL->GetSampler(); + if( pSampler ) + { + auto *pSamplerGL = ValidatedCast<SamplerGLImpl>( pSampler ); + m_ContextState.BindSampler( TextureIndex, pSamplerGL->GetHandle() ); + } + } + + // Texture is now bound to texture slot TextureIndex. + // We now need to set the program uniform to use that slot + if( ProgramPipelineSupported ) + { + // glProgramUniform1i does not require program to be bound to the pipeline + glProgramUniform1i( GLProgramObj, it->Location, TextureIndex ); + } + else + { + // glUniform1i requires program to be bound to the pipeline + glUniform1i( it->Location, TextureIndex ); + } + CHECK_GL_ERROR( "Failed to bind sampler uniform to texture slot" ); + + ++TextureIndex; + } + else + { + LOG_MISSING_BINDING("texture sampler", it->Name) + } + } + + auto &Images = GLProgramObj.GetImages(); + for( auto it = Images.begin(); it != Images.end(); ++it ) + { + auto &pResource = it->pResource; + if( pResource ) + { + CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pResource.RawPtr() ); + auto *pTexViewOGL = static_cast<TextureViewGLImpl*>(pResource.RawPtr()); + const auto &ViewDesc = pTexViewOGL->GetDesc(); + + if( ViewDesc.AccessFlags & UAV_ACCESS_FLAG_WRITE ) + { + auto *pTex = pTexViewOGL->GetTexture(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTex ); + auto *pTexGL = static_cast<TextureBaseGL*>(pTex); + + pTexGL->TextureMemoryBarrier( + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,// Memory accesses using shader image load, store, and atomic built-in + // functions issued after the barrier will reflect data written by shaders + // prior to the barrier. Additionally, image stores and atomics issued after + // the barrier will not execute until all memory accesses (e.g., loads, + // stores, texture fetches, vertex fetches) initiated prior to the barrier + // complete. + m_ContextState); + // We cannot set pending memory barriers here, because + // if some texture is bound twice, the logic will fail + m_BoundWritableTextures.push_back( pTexGL ); + } + +#ifdef _DEBUG + // Check that the texure being bound has immutable storage + { + m_ContextState.BindTexture( -1, pTexViewOGL->GetBindTarget(), pTexViewOGL->GetHandle() ); + GLint IsImmutable = 0; + glGetTexParameteriv( pTexViewOGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable ); + CHECK_GL_ERROR( "glGetTexParameteriv() failed" ); + VERIFY( IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()" ); + m_ContextState.BindTexture( -1, pTexViewOGL->GetBindTarget(), GLObjectWrappers::GLTextureObj(false) ); + } +#endif + auto GlTexFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format ); + // Note that if a format qulifier is specified in the shader, the format + // must match it + + GLboolean Layered = ViewDesc.NumArraySlices > 1 && ViewDesc.FirstArraySlice == 0; + // If "layered" is TRUE, the entire Mip level is bound. Layer parameter is ignored in this + // case. If "layered" is FALSE, only the single layer identified by "layer" will + // be bound. When "layered" is FALSE, the single bound layer is treated as a 2D texture. + GLint Layer = ViewDesc.FirstArraySlice; + + auto GLAccess = AccessFlags2GLAccess( ViewDesc.AccessFlags ); + // WARNING: Texture being bound to the image unit must be complete + // That means that if an integer texture is being bound, its + // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, + // otherwise it will be incomplete + m_ContextState.BindImage( it->BindingPoint, pTexViewOGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat ); + } + else + { + LOG_MISSING_BINDING("image", it->Name) + } + } + + auto &StorageBlocks = GLProgramObj.GetStorageBlocks(); + for( auto it = StorageBlocks.begin(); it != StorageBlocks.end(); ++it ) + { + auto &pResource = it->pResource; + if( pResource ) + { + CHECK_DYNAMIC_TYPE( BufferViewGLImpl, pResource.RawPtr() ); + auto *pBufferViewOGL = static_cast<BufferViewGLImpl*>(pResource.RawPtr()); + const auto &ViewDesc = pBufferViewOGL->GetDesc(); + VERIFY( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Incorrect buffer view type" ); + + auto *pBuffer = pBufferViewOGL->GetBuffer(); + CHECK_DYNAMIC_TYPE( BufferGLImpl, pBuffer ); + auto *pBufferOGL = static_cast<BufferGLImpl*>(pBuffer); + + pBufferOGL->BufferMemoryBarrier( + GL_SHADER_STORAGE_BARRIER_BIT,// Accesses to shader storage blocks after the barrier + // will reflect writes prior to the barrier + m_ContextState); + + glBindBufferRange( GL_SHADER_STORAGE_BUFFER, it->Binding, pBufferOGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth ); + CHECK_GL_ERROR( "Failed to bind shader storage buffer" ); + + m_BoundWritableBuffers.push_back( pBufferOGL ); + } + else + { + LOG_MISSING_BINDING("shader storage block", it->Name ) + } + } + } + + // Go through the list of textures bound as AUVs and set the required memory barriers + for( auto pWritableTex = m_BoundWritableTextures.begin(); pWritableTex != m_BoundWritableTextures.end(); ++pWritableTex ) + { + Uint32 TextureMemBarriers = + GL_TEXTURE_UPDATE_BARRIER_BIT // Writes to a texture via glTex(Sub)Image*, glCopyTex(Sub)Image*, + // glClearTex*Image, glCompressedTex(Sub)Image*, and reads via + // glGetTexImage() after the barrier will reflect data written by + // shaders prior to the barrier + + | GL_TEXTURE_FETCH_BARRIER_BIT // Texture fetches from shaders, including fetches from buffer object + // memory via buffer textures, after the barrier will reflect data + // written by shaders prior to the barrier + + | GL_PIXEL_BUFFER_BARRIER_BIT // Reads and writes of buffer objects via the GL_PIXEL_PACK_BUFFER and + // GL_PIXEL_UNPACK_BUFFER bidnings after the barrier will reflect data + // written by shaders prior to the barrier + + | GL_FRAMEBUFFER_BARRIER_BIT // Reads and writes via framebuffer object attachments after the + // barrier will reflect data written by shaders prior to the barrier. + // Additionally, framebuffer writes issued after the barrier will wait + // on the completion of all shader writes issued prior to the barrier. + + | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; + + NewMemoryBarriers |= TextureMemBarriers; + + // Set new required barriers for the time when texture is used next time + (*pWritableTex)->SetPendingMemoryBarriers( TextureMemBarriers ); + } + + for( auto pWritableBuff = m_BoundWritableBuffers.begin(); pWritableBuff != m_BoundWritableBuffers.end(); ++pWritableBuff ) + { + Uint32 BufferMemoryBarriers = + GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | + GL_ELEMENT_ARRAY_BARRIER_BIT | + GL_UNIFORM_BARRIER_BIT | + GL_COMMAND_BARRIER_BIT | + GL_BUFFER_UPDATE_BARRIER_BIT | + GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT | + GL_SHADER_STORAGE_BARRIER_BIT | + GL_TEXTURE_FETCH_BARRIER_BIT; + + NewMemoryBarriers |= BufferMemoryBarriers; + // Set new required barriers for the time when buffer is used next time + (*pWritableBuff)->SetPendingMemoryBarriers( BufferMemoryBarriers ); + } + } + + void DeviceContextGLImpl::Draw( DrawAttribs &DrawAttribs ) + { + if( DrawAttribs.Topology == PRIMITIVE_TOPOLOGY_UNDEFINED ) + { + LOG_ERROR_MESSAGE("Primitive topology is undefined"); + return; + } + + RefCntWeakPtr<IBuffer> pIndexBuffer; + if( DrawAttribs.IsIndexed ) + pIndexBuffer = m_pIndexBuffer; + + // Obtain strong reference to the vertex description object and index buffer + auto &spVertexDesc = m_pVertexDesc; + auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pDevice.RawPtr()); + if( spVertexDesc ) + { + auto &VAOCache = pRenderDeviceGL->m_VAOCache; + auto spIndexBuff = pIndexBuffer.Lock(); + const auto& VAO = VAOCache.GetVAO( *spVertexDesc, spIndexBuff, m_VertexStreams, m_ContextState ); + m_ContextState.BindVAO( VAO ); + } + else + { + // Draw command will fail if no VAO is bound. If no vertex description is set + // (which is the case if, for instance, the command only inputs VertexID), + // use empty VAO + m_ContextState.BindVAO( pRenderDeviceGL->m_EmptyVAO ); + } + + auto GlTopology = PrimitiveTopologyToGLTopology( DrawAttribs.Topology ); + GLenum IndexType = 0; + Uint32 FirstIndexByteOffset = 0; + if( DrawAttribs.IsIndexed ) + { + IndexType = TypeToGLType( DrawAttribs.IndexType ); + VERIFY( IndexType == GL_UNSIGNED_BYTE || IndexType == GL_UNSIGNED_SHORT || IndexType == GL_UNSIGNED_INT, + "Unsupported index type" ); + VERIFY( m_pIndexBuffer, "Index Buffer is not bound to the pipeline" ); + FirstIndexByteOffset = static_cast<Uint32>(GetValueSize( DrawAttribs.IndexType )) * DrawAttribs.FirstIndexLocation + m_IndexDataStartOffset; + } + + Uint32 NewMemoryBarriers = 0; + BindProgramResources( NewMemoryBarriers ); + + // NOTE: Base Vertex and Base Instance versions are not supported even in OpenGL ES 3.1 + // This functionality can be emulated by adjusting stream offsets. This, however may cause + // errors in case instance data is read from the same stream as vertex data. Thus handling + // such cases is left to the application + + // http://www.opengl.org/wiki/Vertex_Rendering + if( DrawAttribs.IsIndirect ) + { + // The indirect rendering functions take their data from the buffer currently bound to the + // GL_DRAW_INDIRECT_BUFFER binding. Thus, any of indirect draw functions will fail if no buffer is + // bound to that binding. + VERIFY( DrawAttribs.pIndirectDrawAttribs, "Indirect draw command attributes buffer is not set" ); + if( DrawAttribs.pIndirectDrawAttribs ) + { + auto *pBufferOGL = static_cast<BufferGLImpl*>(DrawAttribs.pIndirectDrawAttribs); + + pBufferOGL->BufferMemoryBarrier( + GL_COMMAND_BARRIER_BIT,// Command data sourced from buffer objects by + // Draw*Indirect and DispatchComputeIndirect commands after the barrier + // will reflect data written by shaders prior to the barrier.The buffer + // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER + // and DISPATCH_INDIRECT_BUFFER bindings. + m_ContextState); + + glBindBuffer( GL_DRAW_INDIRECT_BUFFER, pBufferOGL->m_GlBuffer ); + } + + if( DrawAttribs.IsIndexed ) + { + //typedef struct { + // GLuint count; + // GLuint instanceCount; + // GLuint firstIndex; + // GLuint baseVertex; + // GLuint baseInstance; + //} DrawElementsIndirectCommand; + glDrawElementsIndirect( GlTopology, IndexType, reinterpret_cast<const void*>( static_cast<size_t>(DrawAttribs.IndirectDrawArgsOffset) ) ); + // Note that on GLES 3.1, baseInstance is present but reserved and must be zero + CHECK_GL_ERROR( "glDrawElementsIndirect() failed" ); + } + else + { + //typedef struct { + // GLuint count; + // GLuint instanceCount; + // GLuint first; + // GLuint baseInstance; + //} DrawArraysIndirectCommand; + glDrawArraysIndirect( GlTopology, reinterpret_cast<const void*>( static_cast<size_t>(DrawAttribs.IndirectDrawArgsOffset) ) ); + // Note that on GLES 3.1, baseInstance is present but reserved and must be zero + CHECK_GL_ERROR( "glDrawArraysIndirect() failed" ); + } + + glBindBuffer( GL_DRAW_INDIRECT_BUFFER, 0 ); + } + else + { + if( DrawAttribs.NumInstances > 1 ) + { + if( DrawAttribs.IsIndexed ) + { + if( DrawAttribs.BaseVertex ) + { + if( DrawAttribs.FirstInstanceLocation ) + glDrawElementsInstancedBaseVertexBaseInstance( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.NumInstances, DrawAttribs.BaseVertex, DrawAttribs.FirstInstanceLocation ); + else + glDrawElementsInstancedBaseVertex( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.NumInstances, DrawAttribs.BaseVertex ); + } + else + { + if( DrawAttribs.FirstInstanceLocation ) + glDrawElementsInstancedBaseInstance( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.NumInstances, DrawAttribs.FirstInstanceLocation ); + else + glDrawElementsInstanced( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.NumInstances ); + } + } + else + { + if( DrawAttribs.FirstInstanceLocation ) + glDrawArraysInstancedBaseInstance( GlTopology, DrawAttribs.StartVertexLocation, DrawAttribs.NumVertices, DrawAttribs.NumInstances, DrawAttribs.FirstInstanceLocation ); + else + glDrawArraysInstanced( GlTopology, DrawAttribs.StartVertexLocation, DrawAttribs.NumVertices, DrawAttribs.NumInstances ); + } + } + else + { + if( DrawAttribs.IsIndexed ) + { + if( DrawAttribs.BaseVertex ) + glDrawElementsBaseVertex( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.BaseVertex ); + else + glDrawElements( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ) ); + } + else + glDrawArrays( GlTopology, DrawAttribs.StartVertexLocation, DrawAttribs.NumVertices ); + } + CHECK_GL_ERROR( "OpenGL draw command failed" ); + } + + // IMPORTANT: new pending memory barriers in the context must be set + // after all previous barriers were executed. + m_ContextState.SetPendingMemoryBarriers( NewMemoryBarriers ); + } + + void DeviceContextGLImpl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs ) + { + Uint32 NewMemoryBarriers = 0; + BindProgramResources( NewMemoryBarriers ); + + if( DispatchAttrs.pIndirectDispatchAttribs ) + { + CHECK_DYNAMIC_TYPE( BufferGLImpl, DispatchAttrs.pIndirectDispatchAttribs ); + auto *pBufferOGL = static_cast<BufferGLImpl*>(DispatchAttrs.pIndirectDispatchAttribs); + pBufferOGL->BufferMemoryBarrier( + GL_COMMAND_BARRIER_BIT,// Command data sourced from buffer objects by + // Draw*Indirect and DispatchComputeIndirect commands after the barrier + // will reflect data written by shaders prior to the barrier.The buffer + // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER + // and DISPATCH_INDIRECT_BUFFER bindings. + m_ContextState); + + glBindBuffer( GL_DISPATCH_INDIRECT_BUFFER, pBufferOGL->m_GlBuffer ); + CHECK_GL_ERROR( "Failed to bind a buffer for dispatch indirect command" ); + + glDispatchComputeIndirect( DispatchAttrs.DispatchArgsByteOffset ); + CHECK_GL_ERROR( "glDispatchComputeIndirect() failed" ); + + glBindBuffer( GL_DISPATCH_INDIRECT_BUFFER, 0 ); + } + else + { + glDispatchCompute( DispatchAttrs.ThreadGroupCountX, DispatchAttrs.ThreadGroupCountY, DispatchAttrs.ThreadGroupCountZ ); + CHECK_GL_ERROR( "glDispatchCompute() failed" ); + } + + // IMPORTANT: new pending memory barriers in the context must be set + // after all previous barriers were executed. + m_ContextState.SetPendingMemoryBarriers( NewMemoryBarriers ); + } + + void DeviceContextGLImpl::ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil ) + { + // Unlike OpenGL, in D3D10+, the full extent of the resource view is always cleared. + // Viewport and scissor settings are not applied. + if( pView != nullptr ) + { + const auto& ViewDesc = pView->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); + CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pView ); + auto *pViewGL = static_cast<TextureViewGLImpl*>(pView); + if( pView != m_pBoundDepthStencil ) + { + UNEXPECTED( "Depth stencil buffer being cleared is not bound to the pipeline" ); + LOG_ERROR_MESSAGE( "Depth stencil buffer must be bound to the pipeline to be cleared" ); + } + } + else + { + if( !(nullptr == m_pBoundDepthStencil && m_pBoundRenderTargets.size() == 0) ) + { + UNEXPECTED( "Default depth stencil buffer being cleared is not bound to the pipeline" ); + LOG_ERROR_MESSAGE( "Default depth stencil buffer must be bound to the pipeline to be cleared" ); + } + } + Uint32 glClearFlags = 0; + if( ClearFlags & CLEAR_DEPTH_FLAG ) glClearFlags |= GL_DEPTH_BUFFER_BIT; + if( ClearFlags & CLEAR_STENCIL_FLAG ) glClearFlags |= GL_STENCIL_BUFFER_BIT; + glClearDepthf( fDepth ); + glClearStencil( Stencil ); + // If depth writes are disabled, glClear() will not clear depth buffer! + bool DepthWritesEnabled = m_ContextState.GetDepthWritesEnabled(); + m_ContextState.EnableDepthWrites( True ); + bool ScissorTestEnabled = m_ContextState.GetScissorTestEnabled(); + m_ContextState.EnableScissorTest( False ); + // The pixel ownership test, the scissor test, dithering, and the buffer writemasks affect + // the operation of glClear. The scissor box bounds the cleared region. Alpha function, + // blend function, logical operation, stenciling, texture mapping, and depth-buffering + // are ignored by glClear. + glClear(glClearFlags); + CHECK_GL_ERROR( "glClear() failed" ); + m_ContextState.EnableDepthWrites( DepthWritesEnabled ); + m_ContextState.EnableScissorTest( ScissorTestEnabled ); + } + + void DeviceContextGLImpl::ClearRenderTarget( ITextureView *pView, const float *RGBA ) + { + // Unlike OpenGL, in D3D10+, the full extent of the resource view is always cleared. + // Viewport and scissor settings are not applied. + + Int32 RTIndex = -1; + if( pView != nullptr ) + { + const auto& ViewDesc = pView->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); + CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pView ); + auto *pViewGL = static_cast<TextureViewGLImpl*>(pView); + for( Uint32 rt = 0; rt < m_pBoundRenderTargets.size(); ++rt ) + if( m_pBoundRenderTargets[rt] == pView ) + { + RTIndex = rt; + break; + } + + if( RTIndex == -1 ) + { + UNEXPECTED( "Render target being cleared is not bound to the pipeline" ); + LOG_ERROR_MESSAGE( "Render target must be bound to the pipeline to be cleared" ); + } + } + else + { + if( m_pBoundRenderTargets.size() == 0 && m_pBoundDepthStencil == nullptr ) + RTIndex = 0; + else + { + UNEXPECTED( "Default render target must be bound to the pipeline to be cleared" ); + LOG_ERROR_MESSAGE( "Default render target must be bound to the pipeline to be cleared" ); + } + } + + static const float Zero[4] = { 0, 0, 0, 0 }; + if( RGBA == nullptr ) + RGBA = Zero; + + // The pixel ownership test, the scissor test, dithering, and the buffer writemasks affect + // the operation of glClear. The scissor box bounds the cleared region. Alpha function, + // blend function, logical operation, stenciling, texture mapping, and depth-buffering + // are ignored by glClear. + + // Disable scissor test + bool ScissorTestEnabled = m_ContextState.GetScissorTestEnabled(); + m_ContextState.EnableScissorTest( False ); + + // Set write mask + Uint32 WriteMask = 0; + Bool bIndependentBlend = False; + m_ContextState.GetColorWriteMask( RTIndex, WriteMask, bIndependentBlend ); + m_ContextState.SetColorWriteMask( RTIndex, COLOR_MASK_ALL, bIndependentBlend ); + + glClearBufferfv( GL_COLOR, RTIndex, RGBA ); + CHECK_GL_ERROR( "glClearBufferfv() failed" ); + + m_ContextState.SetColorWriteMask( RTIndex, WriteMask, bIndependentBlend ); + m_ContextState.EnableScissorTest( ScissorTestEnabled ); + } + + void DeviceContextGLImpl::Flush() + { + glFlush(); + } + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp new file mode 100644 index 00000000..d3f50635 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp @@ -0,0 +1,280 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "FBOCache.h" +#include "RenderDeviceGLImpl.h" +#include "TextureBaseGL.h" +#include "GLContextState.h" + +namespace Diligent +{ + +bool FBOCache::FBOCacheKey::operator == (const FBOCacheKey &Key)const +{ + if( Hash !=0 && Key.Hash !=0 && Hash != Key.Hash ) + return false; + + if( NumRenderTargets != Key.NumRenderTargets ) + return false; + for( Uint32 rt = 0; rt < NumRenderTargets;++rt ) + { + if( RTIds[rt] != Key.RTIds[rt] ) + return false; + if( RTIds[rt] ) + { + if( !(RTVDescs[rt] == Key.RTVDescs[rt]) ) + return false; + } + } + if( DSId != Key.DSId ) + return false; + if( DSId ) + { + if( !(DSVDesc == Key.DSVDesc) ) + return false; + } + return true; +} + +std::size_t FBOCache::FBOCacheKeyHashFunc::operator() ( const FBOCacheKey& Key )const +{ + if( Key.Hash == 0 ) + { + std::hash<TextureViewDesc> TexViewDescHasher; + Key.Hash = 0; + HashCombine( Key.Hash, Key.NumRenderTargets ); + for( Uint32 rt = 0; rt < Key.NumRenderTargets; ++rt ) + { + HashCombine( Key.Hash, Key.RTIds[rt] ); + if( Key.RTIds[rt] ) + HashCombine( Key.Hash, TexViewDescHasher( Key.RTVDescs[rt] ) ); + } + HashCombine( Key.Hash, Key.DSId ); + if( Key.DSId ) + HashCombine( Key.Hash, TexViewDescHasher( Key.DSVDesc ) ); + } + return Key.Hash; +} + + +FBOCache::FBOCache() +{ + m_Cache.max_load_factor(0.5f); + m_TexIdToKey.max_load_factor(0.5f); +} + +FBOCache::~FBOCache() +{ + VERIFY( m_Cache.empty(), "FBO cache is not empty. Are there any unreleased objects?" ); + VERIFY( m_TexIdToKey.empty(), "TexIdToKey cache is not empty."); +} + +void FBOCache::OnReleaseTexture(ITexture *pTexture) +{ + ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); + auto *pTexGL = ValidatedCast<TextureBaseGL>( pTexture ); + // Find all FBOs that this texture used in + auto EqualRange = m_TexIdToKey.equal_range(pTexGL->GetUniqueID()); + for(auto It = EqualRange.first; It != EqualRange.second; ++It) + { + m_Cache.erase(It->second); + } + m_TexIdToKey.erase(EqualRange.first, EqualRange.second); +} + +const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO( Uint32 NumRenderTargets, + ITextureView *ppRenderTargets[], + ITextureView *pDepthStencil, + GLContextState &ContextState ) +{ + // Pop null render targets from the end of the list + while( NumRenderTargets > 0 && ppRenderTargets[NumRenderTargets - 1] == nullptr ) + --NumRenderTargets; + + if( NumRenderTargets == 0 && pDepthStencil == nullptr ) + { + static const GLObjectWrappers::GLFrameBufferObj DefaultFBO( false ); + return DefaultFBO; + } + + // Lock the cache + ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); + + // Construct the key + FBOCacheKey Key; + VERIFY( NumRenderTargets < MaxRenderTargets, "Too many render targets being set" ); + NumRenderTargets = std::min( NumRenderTargets, MaxRenderTargets ); + Key.NumRenderTargets = NumRenderTargets; + for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + { + auto *pRTView = ppRenderTargets[rt]; + if( !pRTView ) + continue; + + auto *pTex = pRTView->GetTexture(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTex ); + auto *pTexGL = static_cast<TextureBaseGL*>(pTex); + pTexGL->TextureMemoryBarrier( + GL_FRAMEBUFFER_BARRIER_BIT,// Reads and writes via framebuffer object attachments after the + // barrier will reflect data written by shaders prior to the barrier. + // Additionally, framebuffer writes issued after the barrier will wait + // on the completion of all shader writes issued prior to the barrier. + ContextState); + + Key.RTIds[rt] = pTexGL->GetUniqueID(); + Key.RTVDescs[rt] = pRTView->GetDesc(); + } + + if( pDepthStencil ) + { + auto *pTex = pDepthStencil->GetTexture(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTex ); + auto *pTexGL = static_cast<TextureBaseGL*>(pTex); + pTexGL->TextureMemoryBarrier( GL_FRAMEBUFFER_BARRIER_BIT, ContextState ); + Key.DSId = pTexGL->GetUniqueID(); + Key.DSVDesc = pDepthStencil->GetDesc(); + } + + // Try to find FBO in the map + auto It = m_Cache.find(Key); + if( It != m_Cache.end() ) + { + return It->second; + } + else + { + // Create new FBO + GLObjectWrappers::GLFrameBufferObj NewFBO(true); + + ContextState.BindFBO(NewFBO); + + // Initialize FBO + for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + { + if( auto *pRTView = ppRenderTargets[rt] ) + { + auto *pTexture = pRTView->GetTexture(); + const auto &ViewDesc = pRTView->GetDesc(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); + auto *pTexGL = static_cast<TextureBaseGL*>(pTexture); + pTexGL->AttachToFramebuffer( ViewDesc, GL_COLOR_ATTACHMENT0 + rt ); + } + } + + if( auto *pDSView = pDepthStencil ) + { + auto *pTexture = pDSView->GetTexture(); + const auto &ViewDesc = pDSView->GetDesc(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); + auto *pTexGL = static_cast<TextureBaseGL*>(pTexture); + GLenum AttachmentPoint = 0; + if( ViewDesc.Format == TEX_FORMAT_D32_FLOAT || + ViewDesc.Format == TEX_FORMAT_D16_UNORM ) + { + auto GLTexFmt = pTexGL->GetGLTexFormat(); + VERIFY( GLTexFmt == GL_DEPTH_COMPONENT32F || GLTexFmt == GL_DEPTH_COMPONENT16, + "Inappropriate internal texture format (", GLTexFmt, ") for depth attachment. " + "GL_DEPTH_COMPONENT32F or GL_DEPTH_COMPONENT16 is expected"); + + AttachmentPoint = GL_DEPTH_ATTACHMENT; + } + else if( ViewDesc.Format == TEX_FORMAT_D32_FLOAT_S8X24_UINT || + ViewDesc.Format == TEX_FORMAT_D24_UNORM_S8_UINT ) + { + auto GLTexFmt = pTexGL->GetGLTexFormat(); + VERIFY( GLTexFmt == GL_DEPTH24_STENCIL8 || GLTexFmt == GL_DEPTH32F_STENCIL8, + "Inappropriate internal texture format (", GLTexFmt, ") for depth-stencil attachment. " + "GL_DEPTH24_STENCIL8 or GL_DEPTH32F_STENCIL8 is expected"); + + AttachmentPoint = GL_DEPTH_STENCIL_ATTACHMENT; + } + else + { + UNEXPECTED( GetTextureFormatAttribs(ViewDesc.Format).Name, " is not valid depth-stencil view format" ); + } + pTexGL->AttachToFramebuffer( ViewDesc, AttachmentPoint ); + } + + // We now need to set mapping between shader outputs and + // color attachments. This largely redundant step is performed + // by glDrawBuffers() + static const GLenum DrawBuffers[] = + { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3, + GL_COLOR_ATTACHMENT4, + GL_COLOR_ATTACHMENT5, + GL_COLOR_ATTACHMENT6, + GL_COLOR_ATTACHMENT7, + GL_COLOR_ATTACHMENT8, + GL_COLOR_ATTACHMENT9, + GL_COLOR_ATTACHMENT10, + GL_COLOR_ATTACHMENT11, + GL_COLOR_ATTACHMENT12, + GL_COLOR_ATTACHMENT13, + GL_COLOR_ATTACHMENT14, + GL_COLOR_ATTACHMENT15 + }; + // The state set by glDrawBuffers() is part of the state of the framebuffer. + // So it can be set up once and left it set. + glDrawBuffers(NumRenderTargets, DrawBuffers); + CHECK_GL_ERROR( "Failed to set draw buffers via glDrawBuffers()" ); + + GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if( Status != GL_FRAMEBUFFER_COMPLETE ) + { + const Char *StatusString = "Unknown"; + switch( Status ) + { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break; + case GL_FRAMEBUFFER_UNSUPPORTED: StatusString = "GL_FRAMEBUFFER_UNSUPPORTED"; break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; break; + case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; break; + } + LOG_ERROR( "Framebuffer is incomplete. FB status: ", StatusString ); + UNEXPECTED( "Framebuffer is incomplete" ); + } + + auto NewElems = m_Cache.emplace( make_pair(Key, std::move(NewFBO)) ); + // New element must be actually inserted + VERIFY( NewElems.second, "New element was not inserted" ); + if( Key.DSId ) + m_TexIdToKey.insert( make_pair(Key.DSId, Key) ); + for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + { + if( Key.RTIds[rt] ) + m_TexIdToKey.insert( make_pair(Key.RTIds[rt], Key) ); + } + + return NewElems.first->second; + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp new file mode 100644 index 00000000..99ad25d0 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp @@ -0,0 +1,399 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "GLContextAndroid.h" + +#ifndef EGL_CONTEXT_MINOR_VERSION_KHR +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB +#endif + +#ifndef EGL_CONTEXT_MAJOR_VERSION_KHR +#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION +#endif + +namespace Diligent +{ + bool GLContext::InitEGLSurface() + { + display_ = eglGetDisplay( EGL_DEFAULT_DISPLAY ); + if( display_ == EGL_NO_DISPLAY ) + { + LOG_ERROR_AND_THROW( "No EGL display found" ); + } + + auto success = eglInitialize( display_, 0, 0 ); + if( !success ) + { + LOG_ERROR_AND_THROW( "Failed to initialise EGL" ); + } + + /* + * Here specify the attributes of the desired configuration. + * Below, we select an EGLConfig with at least 8 bits per color + * component compatible with on-screen windows + */ + const EGLint attribs[] = + { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //Request opengl ES2.0 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + //EGL_COLORSPACE, EGL_COLORSPACE_sRGB, // does not work + EGL_BLUE_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_RED_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 24, + //EGL_SAMPLE_BUFFERS , 1, + //EGL_SAMPLES , 4, + EGL_NONE + }; + color_size_ = 8; + depth_size_ = 24; + + // Get a list of EGL frame buffer configurations that match specified attributes + EGLint num_configs; + success = eglChooseConfig( display_, attribs, &config_, 1, &num_configs ); + if( !success ) + { + LOG_ERROR_AND_THROW( "Failed to choose config" ); + } + + if( !num_configs ) + { + //Fall back to 16bit depth buffer + const EGLint attribs[] = + { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //Request opengl ES2.0 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_BLUE_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_RED_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 16, + EGL_NONE + }; + success = eglChooseConfig( display_, attribs, &config_, 1, &num_configs ); + if( !success ) + { + LOG_ERROR_AND_THROW( "Failed to choose 16-bit depth config" ); + } + + depth_size_ = 16; + } + + if( !num_configs ) + { + LOG_ERROR_AND_THROW( "Unable to retrieve EGL config" ); + } + + surface_ = eglCreateWindowSurface( display_, config_, window_, NULL ); + if( surface_ == EGL_NO_SURFACE ) + { + LOG_ERROR_AND_THROW( "Failed to create EGLSurface" ); + } + + int32_t screen_width = 0, screen_height = 0; + eglQuerySurface( display_, surface_, EGL_WIDTH, &screen_width ); + eglQuerySurface( display_, surface_, EGL_HEIGHT, &screen_height ); + SwapChainAttribs_.Width = screen_width; + SwapChainAttribs_.Height = screen_height; + + /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is + * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). + * As soon as we picked a EGLConfig, we can safely reconfigure the + * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ + EGLint format; + eglGetConfigAttrib( display_, config_, EGL_NATIVE_VISUAL_ID, &format ); + ANativeWindow_setBuffersGeometry( window_, 0, 0, format ); + + LoadGLFunctions(); + + return true; + } + + bool GLContext::InitEGLContext() + { + major_version_ = 3; + minor_version_ = 1; + + const EGLint context_attribs[] = + { + EGL_CONTEXT_CLIENT_VERSION, major_version_, + EGL_CONTEXT_MINOR_VERSION_KHR, minor_version_, + EGL_NONE + }; + + LOG_INFO_MESSAGE( "contextAttribs: ", context_attribs[0], ' ', context_attribs[1], '\n' ); + LOG_INFO_MESSAGE( "contextAttribs: ", context_attribs[2], ' ', context_attribs[3], '\n' ); + + context_ = eglCreateContext( display_, config_, NULL, context_attribs ); + if( context_ == EGL_NO_CONTEXT ) + { + LOG_ERROR_AND_THROW( "Failed to create EGLContext" ); + } + + if( eglMakeCurrent( display_, surface_, surface_, context_ ) == EGL_FALSE ) + { + LOG_ERROR_AND_THROW( "Unable to eglMakeCurrent" ); + } + + context_valid_ = true; + return true; + } + + void GLContext::InitGLES() + { + if( gles_initialized_ ) + return; + // + //Initialize OpenGL ES 3 if available + // + LOG_INFO_MESSAGE( "GL Version: \n", glGetString( GL_VERSION ), '\n' ); + const char* versionStr = (const char*)glGetString( GL_VERSION ); + if( strstr( versionStr, "OpenGL ES 3." ) +#if USE_GL3_STUB + && gl3stubInit() +#endif + ) + { + es3_supported_ = true; + gl_version_ = 3.0f; + } + else + { + gl_version_ = 2.0f; + } + + gles_initialized_ = true; + } + + bool GLContext::Init( ANativeWindow* window ) + { + if( egl_context_initialized_ ) + return true; + + // + //Initialize EGL + // + window_ = window; + InitEGLSurface(); + InitEGLContext(); + InitGLES(); + + egl_context_initialized_ = true; + + return true; + } + + GLContext::GLContext( const ContextInitInfo &Info, DeviceCaps &DeviceCaps ) : + display_( EGL_NO_DISPLAY ), + surface_( EGL_NO_SURFACE ), + context_( EGL_NO_CONTEXT ), + es3_supported_( false ), + egl_context_initialized_( false ), + gles_initialized_( false ), + major_version_(0), + minor_version_(0), + SwapChainAttribs_(Info.SwapChainAttribs) + { + auto *NativeWindow = reinterpret_cast<ANativeWindow*>(Info.pNativeWndHandle); + Init( NativeWindow ); + + FillDeviceCaps(DeviceCaps); +#if 0 + // Creates table of supported extensions strings + extensions.clear(); + string tmp; + sint32 begin, end; + tmp = string( (char*)glGetString( GL_EXTENSIONS ) ); + + begin = 0; + end = tmp.find( ' ', 0 ); + + DEBUG_PRINT( _L( "Checking Extensions" ) ); + + while( end != string::npos ) + { + DEBUG_PRINT( (_L( "extension %s" )), tmp.substr( begin, end - begin ).c_str() ); + extensions.insert( extensions.end(), tmp.substr( begin, end - begin ) ); + begin = end + 1; + end = tmp.find( ' ', begin ); + } + + if( supportExtension( "GL_INTEL_tessellation" ) ) + { + glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)eglGetProcAddress( "glPatchParameteri" ); + DEBUG_PRINT( _L( "%s = %p" ), "glPatchParameteri", (void*)glPatchParameteri ); + glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)eglGetProcAddress( "glPatchParameterfv" ); + DEBUG_PRINT( _L( "%s = %p" ), "glPatchParameterfv", (void*)glPatchParameterfv ); + } + //if(supportExtension("GL_INTEL_compute_shader")) + { + glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)eglGetProcAddress( "glDispatchCompute" ); + DEBUG_PRINT( _L( "%s = %p" ), "glDispatchCompute", (void*)glDispatchCompute ); + glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)eglGetProcAddress( "glBindImageTexture" ); + DEBUG_PRINT( _L( "%s = %p" ), "glBindImageTexture", (void*)glBindImageTexture ); + } +#endif + } + + GLContext::~GLContext() + { + Terminate(); + } + + void GLContext::SwapBuffers() + { + bool b = eglSwapBuffers( display_, surface_ ); + if( !b ) + { + EGLint err = eglGetError(); + if( err == EGL_BAD_SURFACE ) + { + //Recreate surface + InitEGLSurface(); + //return EGL_SUCCESS; //Still consider glContext is valid + } + else if( err == EGL_CONTEXT_LOST || err == EGL_BAD_CONTEXT ) + { + //Context has been lost!! + context_valid_ = false; + Terminate(); + InitEGLContext(); + } + //return err; + } + //return EGL_SUCCESS; + } + + void GLContext::Terminate() + { + if( display_ != EGL_NO_DISPLAY ) + { + eglMakeCurrent( display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); + if( context_ != EGL_NO_CONTEXT ) + { + eglDestroyContext( display_, context_ ); + } + + if( surface_ != EGL_NO_SURFACE ) + { + eglDestroySurface( display_, surface_ ); + } + eglTerminate( display_ ); + } + + display_ = EGL_NO_DISPLAY; + context_ = EGL_NO_CONTEXT; + surface_ = EGL_NO_SURFACE; + context_valid_ = false; + } + + + EGLint GLContext::Resume( ANativeWindow* window ) + { + if( egl_context_initialized_ == false ) + { + Init( window ); + return EGL_SUCCESS; + } + + + //Create surface + window_ = window; + surface_ = eglCreateWindowSurface( display_, config_, window_, NULL ); + int32_t new_screen_width = 0; + int32_t new_screen_height = 0; + eglQuerySurface( display_, surface_, EGL_WIDTH, &new_screen_width ); + eglQuerySurface( display_, surface_, EGL_HEIGHT, &new_screen_height ); + + if( new_screen_width != SwapChainAttribs_.Width || new_screen_height != SwapChainAttribs_.Height ) + { + //Screen resized + LOG_INFO_MESSAGE( "Screen resized\n" ); + } + + if( eglMakeCurrent( display_, surface_, surface_, context_ ) == EGL_TRUE ) + return EGL_SUCCESS; + + EGLint err = eglGetError(); + LOG_WARNING_MESSAGE( "Unable to eglMakeCurrent ", err, '\n' ); + + if( err == EGL_CONTEXT_LOST ) + { + //Recreate context + LOG_INFO_MESSAGE( "Re-creating egl context\n" ); + InitEGLContext(); + } + else + { + //Recreate surface + Terminate(); + InitEGLSurface(); + InitEGLContext(); + } + + return err; + + } + + void GLContext::Suspend() + { + if( surface_ != EGL_NO_SURFACE ) + { + eglDestroySurface( display_, surface_ ); + surface_ = EGL_NO_SURFACE; + } + } + + bool GLContext::Invalidate() + { + Terminate(); + + egl_context_initialized_ = false; + return true; + } + + void GLContext::FillDeviceCaps( DeviceCaps &DeviceCaps ) + { + DeviceCaps.DevType = DeviceType::OpenGLES; + DeviceCaps.MajorVersion = major_version_; + DeviceCaps.MinorVersion = minor_version_; + bool IsGLES31OrAbove = (major_version_ >= 4 || major_version_ == 3 && minor_version_ >= 1); + DeviceCaps.bSeparableProgramSupported = IsGLES31OrAbove; + DeviceCaps.bIndirectRenderingSupported = IsGLES31OrAbove; + + auto &SamCaps = DeviceCaps.SamCaps; + SamCaps.bBorderSamplingModeSupported = GL_TEXTURE_BORDER_COLOR && IsGLES31OrAbove; + SamCaps.bAnisotropicFilteringSupported = GL_TEXTURE_MAX_ANISOTROPY_EXT && IsGLES31OrAbove; + SamCaps.bLODBiasSupported = GL_TEXTURE_LOD_BIAS && IsGLES31OrAbove; + + auto &TexCaps = DeviceCaps.TexCaps; + TexCaps.bTexture1DSupported = False; // Not supported in GLES 3.1 + TexCaps.bTexture1DArraySupported = False; // Not supported in GLES 3.1 + TexCaps.bTexture2DMSSupported = IsGLES31OrAbove; + TexCaps.bTexture2DMSArraySupported = False; // Not supported in GLES 3.1 + TexCaps.bTextureViewSupported = False; // Not supported in GLES 3.1 + } +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp new file mode 100644 index 00000000..065f3a16 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp @@ -0,0 +1,647 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "GLContextState.h" +#include "TextureBaseGL.h" +#include "SamplerGLImpl.h" +#include "AsyncWritableResource.h" +#include "GLTypeConversions.h" +#include "BufferViewGLImpl.h" +#include "RenderDeviceGLImpl.h" + +using namespace GLObjectWrappers; +using namespace Diligent; + +namespace Diligent +{ + GLContextState::GLContextState( RenderDeviceGLImpl *pDeviceGL ) : + m_PendingMemoryBarriers( 0 ), + m_DepthCmpFunc( COMPARISON_FUNC_UNKNOW ), + m_StencilReadMask( 0xFF ), + m_StencilWriteMask( 0xFF ), + m_GLProgId( 0 ), + m_GLPipelineId( 0 ), + m_VAOId( 0 ), + m_FBOId( 0 ), + m_iActiveTexture(-1) + { + const DeviceCaps &DeviceCaps = pDeviceGL->GetDeviceCaps(); + m_Caps.bFillModeSelectionSupported = DeviceCaps.bWireframeFillSupported; + + { + m_Caps.m_iMaxCombinedTexUnits = 0; + glGetIntegerv( GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &m_Caps.m_iMaxCombinedTexUnits ); + CHECK_GL_ERROR( "Failed to get max combined tex image units count" ); + m_Caps.m_iMaxCombinedTexUnits = std::max( m_Caps.m_iMaxCombinedTexUnits, 80 ); // Must be at least 80 in GL4.2 + } + + m_BoundTextures.reserve( m_Caps.m_iMaxCombinedTexUnits ); + m_BoundSamplers.reserve( 32 ); + m_pBoundImages.reserve( 32 ); + + for( Uint32 rt = 0; rt < _countof( m_ColorWriteMasks ); ++rt ) + m_ColorWriteMasks[rt] = COLOR_MASK_ALL; + } + + template<typename ObjectType> + bool UpdateBoundObject( UniqueIdentifier &CurrentObjectID, const ObjectType &NewObject, GLuint &NewGLHandle ) + { + NewGLHandle = static_cast<GLuint>(NewObject); + UniqueIdentifier NewObjectID = 0; + if( NewGLHandle != 0 ) + { + // Only ask for the ID if the object handle is non-zero + // to avoid ID generation for null objects + NewObjectID = NewObject.GetUniqueID(); + } + + // It is unsafe to use GL handle to keep track of bound textures + // When a texture is released, GL is free to reuse its handle for + // the new created textures + if( CurrentObjectID != NewObjectID ) + { + CurrentObjectID = NewObjectID; + return true; + } + return false; + } + + void GLContextState::SetProgram( const GLProgramObj &GLProgram ) + { + GLuint GLProgHandle = 0; + if( UpdateBoundObject( m_GLProgId, GLProgram, GLProgHandle ) ) + { + glUseProgram( GLProgHandle ); + CHECK_GL_ERROR( "Failed to set GL program" ); + } + } + + void GLContextState::SetPipeline( const GLPipelineObj &GLPipeline ) + { + GLuint GLPipelineHandle = 0; + if( UpdateBoundObject( m_GLPipelineId, GLPipeline, GLPipelineHandle ) ) + { + glBindProgramPipeline( GLPipelineHandle ); + CHECK_GL_ERROR( "Failed to bind program pipeline" ); + } + } + + void GLContextState::BindVAO( const GLVertexArrayObj &VAO ) + { + GLuint VAOHandle = 0; + if( UpdateBoundObject( m_VAOId, VAO, VAOHandle ) ) + { + VERIFY( VAOHandle, "VAO Handle is zero" ); + glBindVertexArray( VAOHandle ); + CHECK_GL_ERROR( "Failed to set VAO" ); + } + } + + void GLContextState::BindFBO( const GLFrameBufferObj &FBO ) + { + GLuint FBOHandle = 0; + if( UpdateBoundObject( m_FBOId, FBO, FBOHandle ) ) + { + // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT + // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. + // Binding a new framebuffer will NOT affect the mask. + + // NOTE: if attachment image is a NON-immutable format texture and the selected + // level is NOT level_base, the texture MUST BE MIPMAP COMPLETE + // If image is part of a cubemap texture, the texture must also be mipmap cube complete. + glBindFramebuffer( GL_DRAW_FRAMEBUFFER, FBOHandle ); + CHECK_GL_ERROR( "Failed to bind FBO as draw framebuffer" ); + glBindFramebuffer( GL_READ_FRAMEBUFFER, FBOHandle ); + CHECK_GL_ERROR( "Failed to bind FBO as read framebuffer" ); + } + } + + template<class ObjectType> + bool UpdateBoundObjectsArr( std::vector< UniqueIdentifier >& BoundObjectIDs, Uint32 Index, const ObjectType &NewObject, GLuint &NewGLHandle ) + { + if( Index >= BoundObjectIDs.size() ) + BoundObjectIDs.resize( Index + 1 ); + + return UpdateBoundObject( BoundObjectIDs[Index], NewObject, NewGLHandle ); + } + + void GLContextState::SetActiveTexture( Int32 Index ) + { + if( Index < 0 ) + { + Index += m_Caps.m_iMaxCombinedTexUnits; + } + VERIFY( 0 <= Index && Index < m_Caps.m_iMaxCombinedTexUnits, "Texture unit is out of range" ); + + if( m_iActiveTexture != Index ) + { + glActiveTexture( GL_TEXTURE0 + Index ); + CHECK_GL_ERROR( "Failed to activate texture slot ", Index ); + m_iActiveTexture = Index; + } + } + + void GLContextState::BindTexture( Int32 Index, GLenum BindTarget, const GLObjectWrappers::GLTextureObj &Tex) + { + if( Index < 0 ) + { + Index += m_Caps.m_iMaxCombinedTexUnits; + } + VERIFY( 0 <= Index && Index < m_Caps.m_iMaxCombinedTexUnits, "Texture unit is out of range" ); + + // Always update active texture unit + SetActiveTexture( Index ); + + GLuint GLTexHandle = 0; + if( UpdateBoundObjectsArr( m_BoundTextures, Index, Tex, GLTexHandle ) ) + { + glBindTexture( BindTarget, GLTexHandle ); + CHECK_GL_ERROR( "Failed to bind texture to slot ", Index ); + } + } + + void GLContextState::BindSampler( Uint32 Index, const GLObjectWrappers::GLSamplerObj &GLSampler) + { + GLuint GLSamplerHandle = 0; + if( UpdateBoundObjectsArr( m_BoundSamplers, Index, GLSampler, GLSamplerHandle ) ) + { + glBindSampler( Index, GLSamplerHandle ); + CHECK_GL_ERROR( "Failed to bind sampler to slot ", Index ); + } + } + + void GLContextState::BindImage( Uint32 Index, + TextureViewGLImpl *pTexView, + GLint MipLevel, + GLboolean IsLayered, + GLint Layer, + GLenum Access, + GLenum Format ) + { + BoundImageInfo NewImageInfo( + pTexView->GetUniqueID(), + MipLevel, + IsLayered, + Layer, + Access, + Format + ); + if( Index >= m_pBoundImages.size() ) + m_pBoundImages.resize( Index + 1 ); + if( !(m_pBoundImages[Index] == NewImageInfo) ) + { + m_pBoundImages[Index] = NewImageInfo; + GLint GLTexHandle = pTexView->GetHandle(); + glBindImageTexture( Index, GLTexHandle, MipLevel, IsLayered, Layer, Access, Format ); + CHECK_GL_ERROR( "glBindImageTexture() failed" ); + } + } + + void GLContextState::EnsureMemoryBarrier( Uint32 RequiredBarriers, AsyncWritableResource *pRes/* = nullptr */ ) + { + // Every resource tracks its own pending memory barriers. + // Device context also tracks which barriers have not been executed + // When a resource with pending memory barrier flag is bound to the context, + // the context checks if the same flag is set in its own pending barriers. + // Thus a memory barrier is only executed if some resource required that barrier + // and it has not been executed yet. This is almost optimal strategy, but slightly + // imperfect as the following scenario shows: + + // Draw 1: Barriers_A |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG + // Draw 2: Barriers_B |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG + // Draw 3: Bind B, execute BARRIER: Barriers_B = 0, Barrier_Ctx = 0 (Barriers_A == BARRIER_FLAG) + // Draw 4: Barriers_B |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG + // Draw 5: Bind A, execute BARRIER, Barriers_A = 0, Barrier_Ctx = 0 (Barriers_B == BARRIER_FLAG) + + // In the last draw call, barrier for resource A has already been executed when resource B was + // bound to the pipeline. Since Resource A has not been bound since then, its flag has not been + // cleared. + // This situation does not seem to be a problem though since a barier cannot be executed + // twice in any situation + + Uint32 ResourcePendingBarriers = 0; + if( pRes ) + { + // If resource is specified, only set up memory barriers + // that are required by the resource + ResourcePendingBarriers = pRes->GetPendingMemortBarriers(); + RequiredBarriers &= ResourcePendingBarriers; + } + + // Leave only pending barriers + RequiredBarriers &= m_PendingMemoryBarriers; + if( RequiredBarriers ) + { + glMemoryBarrier( RequiredBarriers ); + CHECK_GL_ERROR( "glMemoryBarrier() failed" ); + m_PendingMemoryBarriers &= ~RequiredBarriers; + } + + // Leave only these barriers that are still pending + if( pRes ) + pRes->ResetPendingMemoryBarriers( m_PendingMemoryBarriers & ResourcePendingBarriers ); + } + + void GLContextState::SetPendingMemoryBarriers( Uint32 PendingBarriers ) + { + m_PendingMemoryBarriers |= PendingBarriers; + } + + void GLContextState::EnableDepthTest( bool bEnable ) + { + if( m_DepthEnableState != bEnable ) + { + if( bEnable ) + { + glEnable( GL_DEPTH_TEST ); + CHECK_GL_ERROR( "Failed to enable detph test" ); + } + else + { + glDisable( GL_DEPTH_TEST ); + CHECK_GL_ERROR( "Failed to disable detph test" ); + } + m_DepthEnableState = bEnable; + } + } + + void GLContextState::EnableDepthWrites( bool bEnable ) + { + if( m_DepthWritesEnableState != bEnable ) + { + // If mask is non-zero, the depth buffer is enabled for writing; otherwise, it is disabled. + glDepthMask( bEnable ? 1 : 0 ); + CHECK_GL_ERROR( "Failed to enale/disable depth writes" ); + m_DepthWritesEnableState = bEnable; + } + } + + void GLContextState::SetDepthFunc( COMPARISON_FUNCTION CmpFunc ) + { + if( m_DepthCmpFunc != CmpFunc ) + { + auto GlCmpFunc = CompareFuncToGLCompareFunc( CmpFunc ); + glDepthFunc( GlCmpFunc ); + CHECK_GL_ERROR( "Failed to set GL comparison function" ); + m_DepthCmpFunc = CmpFunc; + } + } + + void GLContextState::EnableStencilTest( bool bEnable ) + { + if( m_StencilTestEnableState != bEnable ) + { + if( bEnable ) + { + glEnable( GL_STENCIL_TEST ); + CHECK_GL_ERROR( "Failed to enable stencil test" ); + } + else + { + glDisable( GL_STENCIL_TEST ); + CHECK_GL_ERROR( "Failed to disable stencil test" ); + } + m_StencilTestEnableState = bEnable; + } + } + + void GLContextState::SetStencilWriteMask( Uint8 StencilWriteMask ) + { + if( m_StencilWriteMask != StencilWriteMask ) + { + glStencilMask( StencilWriteMask ); + m_StencilWriteMask = StencilWriteMask; + } + } + + void GLContextState::SetStencilFunc( GLenum Face, COMPARISON_FUNCTION Func, Int32 Ref, Uint32 Mask ) + { + auto& FaceStencilOp = m_StencilOpState[Face == GL_FRONT ? 0 : 1]; + if( FaceStencilOp.Func != Func || + FaceStencilOp.Ref != Ref || + FaceStencilOp.Mask != Mask ) + { + auto GlStencilFunc = CompareFuncToGLCompareFunc( Func ); + glStencilFuncSeparate( Face, GlStencilFunc, Ref, Mask ); + CHECK_GL_ERROR( "Failed to set stencil function" ); + + FaceStencilOp.Func = Func; + FaceStencilOp.Ref = Ref; + FaceStencilOp.Mask = Mask; + } + } + + void GLContextState::SetStencilOp( GLenum Face, STENCIL_OP StencilFailOp, STENCIL_OP StencilDepthFailOp, STENCIL_OP StencilPassOp ) + { + auto& FaceStencilOp = m_StencilOpState[Face == GL_FRONT ? 0 : 1]; + if( FaceStencilOp.StencilFailOp != StencilFailOp || + FaceStencilOp.StencilDepthFailOp != StencilDepthFailOp || + FaceStencilOp.StencilPassOp != StencilPassOp ) + { + auto glsfail = StencilOp2GlStencilOp( StencilFailOp ); + auto dpfail = StencilOp2GlStencilOp( StencilDepthFailOp ); + auto dppass = StencilOp2GlStencilOp( StencilPassOp ); + + glStencilOpSeparate( Face, glsfail, dpfail, dppass ); + CHECK_GL_ERROR( "Failed to set stencil operation" ); + + FaceStencilOp.StencilFailOp = StencilFailOp; + FaceStencilOp.StencilDepthFailOp = StencilDepthFailOp; + FaceStencilOp.StencilPassOp = StencilPassOp; + } + } + + void GLContextState::SetFillMode( FILL_MODE FillMode ) + { + if( m_Caps.bFillModeSelectionSupported ) + { + if( m_RSState.FillMode != FillMode ) + { + auto PolygonMode = FillMode == FILL_MODE_WIREFRAME ? GL_LINE : GL_FILL; + glPolygonMode( GL_FRONT_AND_BACK, PolygonMode ); + CHECK_GL_ERROR( "Failed to set polygon mode" ); + + m_RSState.FillMode = FillMode; + } + } + else + { + if( FillMode == FILL_MODE_WIREFRAME ) + LOG_WARNING_MESSAGE( "Wireframe fill mode is not supported on this device\n" ); + } + } + + void GLContextState::SetCullMode( CULL_MODE CullMode ) + { + if( m_RSState.CullMode != CullMode ) + { + if( CullMode == CULL_MODE_NONE ) + { + glDisable( GL_CULL_FACE ); + CHECK_GL_ERROR( "Failed to disable face culling" ); + } + else + { + VERIFY( CullMode == CULL_MODE_FRONT || CullMode == CULL_MODE_BACK, "Unexpected cull mode" ); + glEnable( GL_CULL_FACE ); + CHECK_GL_ERROR( "Failed to enable face culling" ); + auto CullFace = CullMode == CULL_MODE_BACK ? GL_BACK : GL_FRONT; + glCullFace( CullFace ); + CHECK_GL_ERROR( "Failed to set cull face" ); + } + + m_RSState.CullMode = CullMode; + } + } + + void GLContextState::SetFrontFace( Bool FrontCounterClockwise ) + { + if( m_RSState.FrontCounterClockwise != FrontCounterClockwise ) + { + auto FrontFace = FrontCounterClockwise ? GL_CCW : GL_CW; + glFrontFace( FrontFace ); + CHECK_GL_ERROR( "Failed to set front face" ); + m_RSState.FrontCounterClockwise = FrontCounterClockwise; + } + } + + void GLContextState::SetDepthBias( float fDepthBias, float fSlopeScaledDepthBias ) + { + if( m_RSState.fDepthBias != fDepthBias || + m_RSState.fSlopeScaledDepthBias != fSlopeScaledDepthBias ) + { + if( fDepthBias != 0 || fSlopeScaledDepthBias != 0 ) + { + glEnable( GL_POLYGON_OFFSET_FILL ); + CHECK_GL_ERROR( "Failed to enable polygon offset fill" ); + } + else + { + glDisable( GL_POLYGON_OFFSET_FILL ); + CHECK_GL_ERROR( "Failed to disable polygon offset fill" ); + } + + glPolygonOffset( fSlopeScaledDepthBias, fDepthBias ); + CHECK_GL_ERROR( "Failed to set polygon offset" ); + + m_RSState.fDepthBias = fDepthBias; + m_RSState.fSlopeScaledDepthBias = fSlopeScaledDepthBias; + } + } + + void GLContextState::SetDepthClamp( Bool bEnableDepthClamp ) + { + if( m_RSState.DepthClampEnable != bEnableDepthClamp ) + { + if( bEnableDepthClamp ) + { + if( GL_DEPTH_CLAMP ) + { + glEnable( GL_DEPTH_CLAMP ); + CHECK_GL_ERROR( "Failed to enable depth clamp" ); + } + } + else + { + if( GL_DEPTH_CLAMP ) + { + // WARNING: on OpenGL, depth clamping is disabled against + // both far and near clip planes. On DirectX, only clipping + // against far clip plane can be disabled + glDisable( GL_DEPTH_CLAMP ); + CHECK_GL_ERROR( "Failed to disable depth clamp" ); + } + else + { + LOG_WARNING_MESSAGE( "Disabling depth clamp is not supported" ) + } + } + m_RSState.DepthClampEnable = bEnableDepthClamp; + } + } + + void GLContextState::EnableScissorTest( Bool bEnableScissorTest ) + { + if( m_RSState.ScissorTestEnable != bEnableScissorTest ) + { + if( bEnableScissorTest ) + { + glEnable( GL_SCISSOR_TEST ); + CHECK_GL_ERROR( "Failed to enable scissor test" ); + } + else + { + glDisable( GL_SCISSOR_TEST ); + CHECK_GL_ERROR( "Failed to disable scissor clamp" ); + } + + m_RSState.ScissorTestEnable = bEnableScissorTest; + } + } + + void GLContextState::SetBlendState( const BlendStateDesc &BSDsc, const float *BlendFactors, Uint32 SampleMask ) + { + bool bEnableBlend = false; + if( BSDsc.IndependentBlendEnable ) + { + for( int i = 0; i < BSDsc.MaxRenderTargets; ++i ) + { + const auto& RT = BSDsc.RenderTargets[i]; + if( RT.BlendEnable ) + bEnableBlend = true; + + SetColorWriteMask(i, RT.RenderTargetWriteMask, True); + } + } + else + { + const auto& RT0 = BSDsc.RenderTargets[0]; + bEnableBlend = RT0.BlendEnable; + SetColorWriteMask(0, RT0.RenderTargetWriteMask, False); + } + + if( bEnableBlend ) + { + // Sets the blend enable flag for ALL color buffers. + glEnable( GL_BLEND ); + CHECK_GL_ERROR( "Failed to enable alpha blending" ); + + glBlendColor( BlendFactors[0], BlendFactors[1], BlendFactors[2], BlendFactors[3] ); + CHECK_GL_ERROR( "Failed to set blend color" ); + + if( BSDsc.AlphaToCoverageEnable ) + { + glEnable( GL_SAMPLE_ALPHA_TO_COVERAGE ); + CHECK_GL_ERROR( "Failed to enable alpha to coverage" ); + } + else + { + glDisable( GL_SAMPLE_ALPHA_TO_COVERAGE ); + CHECK_GL_ERROR( "Failed to disable alpha to coverage" ); + } + + if( BSDsc.IndependentBlendEnable ) + { + for( int i = 0; i < BSDsc.MaxRenderTargets; ++i ) + { + const auto& RT = BSDsc.RenderTargets[i]; + if( RT.BlendEnable ) + { + glEnablei( GL_BLEND, i ); + CHECK_GL_ERROR( "Failed to enable alpha blending" ); + + auto srcFactorRGB = BlendFactor2GLBlend( RT.SrcBlend ); + auto dstFactorRGB = BlendFactor2GLBlend( RT.DestBlend ); + auto srcFactorAlpha = BlendFactor2GLBlend( RT.SrcBlendAlpha ); + auto dstFactorAlpha = BlendFactor2GLBlend( RT.DestBlendAlpha ); + glBlendFuncSeparatei( i, srcFactorRGB, dstFactorRGB, srcFactorAlpha, dstFactorAlpha ); + CHECK_GL_ERROR( "Failed to set blending factors" ); + + auto modeRGB = BlendOperation2GLBlendOp( RT.BlendOp ); + auto modeAlpha = BlendOperation2GLBlendOp( RT.BlendOpAlpha ); + glBlendEquationSeparatei( i, modeRGB, modeAlpha ); + CHECK_GL_ERROR( "Failed to set blending equations" ); + } + else + { + glDisablei( GL_BLEND, i ); + CHECK_GL_ERROR( "Failed to disable alpha blending" ); + } + } + } + else + { + const auto& RT0 = BSDsc.RenderTargets[0]; + auto srcFactorRGB = BlendFactor2GLBlend( RT0.SrcBlend ); + auto dstFactorRGB = BlendFactor2GLBlend( RT0.DestBlend ); + auto srcFactorAlpha = BlendFactor2GLBlend( RT0.SrcBlendAlpha ); + auto dstFactorAlpha = BlendFactor2GLBlend( RT0.DestBlendAlpha ); + glBlendFuncSeparate( srcFactorRGB, dstFactorRGB, srcFactorAlpha, dstFactorAlpha ); + CHECK_GL_ERROR( "Failed to set blending factors" ); + + auto modeRGB = BlendOperation2GLBlendOp( RT0.BlendOp ); + auto modeAlpha = BlendOperation2GLBlendOp( RT0.BlendOpAlpha ); + glBlendEquationSeparate( modeRGB, modeAlpha ); + CHECK_GL_ERROR( "Failed to set blending equations" ); + } + } + else + { + // Sets the blend disable flag for ALL color buffers. + glDisable( GL_BLEND ); + CHECK_GL_ERROR( "Failed to disable alpha blending" ); + } + } + + void GLContextState::SetColorWriteMask( Uint32 RTIndex, Uint32 WriteMask, Bool bIsIndependent ) + { + // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT + // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. + // Binding a new framebuffer will NOT affect the mask. + + if( !bIsIndependent ) + RTIndex = 0; + + if( m_ColorWriteMasks[RTIndex] != WriteMask || + m_bIndependentWriteMasks != bIsIndependent ) + { + if( bIsIndependent ) + { + // Note that glColorMaski() does not set color mask for the framebuffer + // attachment point RTIndex. Rather it sets the mask for what was set + // by the glDrawBuffers() function for the i-th output + glColorMaski( RTIndex, + (WriteMask & COLOR_MASK_RED) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_GREEN) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_BLUE) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_ALPHA) ? GL_TRUE : GL_FALSE ); + CHECK_GL_ERROR( "Failed to set GL color mask" ); + + m_ColorWriteMasks[RTIndex] = WriteMask; + } + else + { + // glColorMask() sets the mask for ALL draw buffers + glColorMask( (WriteMask & COLOR_MASK_RED) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_GREEN) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_BLUE) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_ALPHA) ? GL_TRUE : GL_FALSE ); + CHECK_GL_ERROR( "Failed to set GL color mask" ); + + for( int rt = 0; rt < _countof( m_ColorWriteMasks ); ++rt ) + m_ColorWriteMasks[rt] = WriteMask; + } + m_bIndependentWriteMasks = bIsIndependent; + } + } + + void GLContextState::GetColorWriteMask( Uint32 RTIndex, Uint32 &WriteMask, Bool &bIsIndependent ) + { + if( !m_bIndependentWriteMasks ) + RTIndex = 0; + WriteMask = m_ColorWriteMasks[ RTIndex ]; + bIsIndependent = m_bIndependentWriteMasks; + } +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp new file mode 100644 index 00000000..a0e7bf0b --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp @@ -0,0 +1,233 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "GLContextWindows.h" +#include "DeviceCaps.h" +#include "GLTypeConversions.h" + +namespace Diligent +{ + + void APIENTRY openglCallbackFunction( GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + void* userParam ) + { + std::stringstream MessageSS; + + MessageSS << std::endl << "OPENGL DEBUG MESSAGE: " << message << std::endl; + MessageSS << "Type: "; + switch( type ) { + case GL_DEBUG_TYPE_ERROR: + MessageSS << "ERROR"; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + MessageSS << "DEPRECATED_BEHAVIOR"; + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + MessageSS << "UNDEFINED_BEHAVIOR"; + break; + case GL_DEBUG_TYPE_PORTABILITY: + MessageSS << "PORTABILITY"; + break; + case GL_DEBUG_TYPE_PERFORMANCE: + MessageSS << "PERFORMANCE"; + break; + case GL_DEBUG_TYPE_OTHER: + MessageSS << "OTHER"; + break; + } + MessageSS << std::endl; + + MessageSS << "Severity: "; + switch( severity ){ + case GL_DEBUG_SEVERITY_LOW: + MessageSS << "LOW"; + break; + case GL_DEBUG_SEVERITY_MEDIUM: + MessageSS << "MEDIUM"; + break; + case GL_DEBUG_SEVERITY_HIGH: + MessageSS << "HIGH"; + break; + } + MessageSS << std::endl; + + //MessageSS << "Id: "<< id << std::endl; + + OutputDebugStringA( MessageSS.str().c_str() ); + } + + GLContext::GLContext( const ContextInitInfo &Info, DeviceCaps &DeviceCaps ) : + m_SwapChainAttribs(Info.SwapChainAttribs), + m_Context(0), + m_WindowHandleToDeviceContext(0) + { + Int32 MajorVersion = 0, MinorVersion = 0; + if(Info.pNativeWndHandle != nullptr) + { + HWND hWnd = reinterpret_cast<HWND>(Info.pNativeWndHandle); + RECT rc; + GetClientRect( hWnd, &rc ); + m_SwapChainAttribs.Width = rc.right - rc.left; + m_SwapChainAttribs.Height = rc.bottom - rc.top; + + // See http://www.opengl.org/wiki/Tutorial:_OpenGL_3.1_The_First_Triangle_(C%2B%2B/Win) + // http://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL) + PIXELFORMATDESCRIPTOR pfd; + memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) ); + pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR ); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 32; + pfd.iLayerType = PFD_MAIN_PLANE; + + + m_WindowHandleToDeviceContext = GetDC( hWnd ); + int nPixelFormat = ChoosePixelFormat( m_WindowHandleToDeviceContext, &pfd ); + + if( nPixelFormat == 0 ) + LOG_ERROR_AND_THROW( "Invalid Pixel Format" ); + + BOOL bResult = SetPixelFormat( m_WindowHandleToDeviceContext, nPixelFormat, &pfd ); + if( !bResult ) + LOG_ERROR_AND_THROW( "Failed to set Pixel Format" ); + + // Create standard OpenGL (2.1) rendering context which will be used only temporarily, + HGLRC tempContext = wglCreateContext( m_WindowHandleToDeviceContext ); + // and make it current + wglMakeCurrent( m_WindowHandleToDeviceContext, tempContext ); + + // Initialize GLEW + GLenum err = glewInit(); + if( GLEW_OK != err ) + LOG_ERROR_AND_THROW( "Failed to initialize GLEW" ); + + + if( wglewIsSupported( "WGL_ARB_create_context" ) == 1 ) + { + MajorVersion = 4; + MinorVersion = 2; + // Setup attributes for a new OpenGL 4.2 rendering context + int attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, MajorVersion, + WGL_CONTEXT_MINOR_VERSION_ARB, MinorVersion, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + GL_CONTEXT_PROFILE_MASK, GL_CONTEXT_CORE_PROFILE_BIT, + 0, 0 + }; + + #ifdef _DEBUG + attribs[5] |= WGL_CONTEXT_DEBUG_BIT_ARB; + #endif + + // Create new rendering context + // In order to create new OpenGL rendering context we have to call function wglCreateContextAttribsARB(), + // which is an OpenGL function and requires OpenGL to be active when it is called. + // The only way is to create an old context, activate it, and while it is active create a new one. + // Very inconsistent, but we have to live with it! + m_Context = wglCreateContextAttribsARB( m_WindowHandleToDeviceContext, 0, attribs ); + + // Delete tempContext + wglMakeCurrent( NULL, NULL ); + wglDeleteContext( tempContext ); + // + wglMakeCurrent( m_WindowHandleToDeviceContext, m_Context ); + wglSwapIntervalEXT( 0 ); + } + else + { //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before) + m_Context = tempContext; + } + } + else + { + auto CurrentCtx = wglGetCurrentContext(); + m_WindowHandleToDeviceContext = wglGetCurrentDC(); + if (CurrentCtx != 0) + { + LOG_INFO_MESSAGE("Attaching to existing OpenGL context") + } + else + { + LOG_ERROR_AND_THROW("No current GL context found! Provide non-null handle to a native Window to create a GL context") + } + + // Initialize GLEW + GLenum err = glewInit(); + if( GLEW_OK != err ) + LOG_ERROR_AND_THROW( "Failed to initialize GLEW" ); + } + + //Checking GL version + const GLubyte *GLVersionString = glGetString( GL_VERSION ); + + //Or better yet, use the GL3 way to get the version number + glGetIntegerv( GL_MAJOR_VERSION, &MajorVersion ); + glGetIntegerv( GL_MINOR_VERSION, &MinorVersion ); + + if( glDebugMessageCallback ) + { + glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS ); + glDebugMessageCallback( openglCallbackFunction, nullptr ); + GLuint unusedIds = 0; + glDebugMessageControl( GL_DONT_CARE, + GL_DONT_CARE, + GL_DONT_CARE, + 0, + &unusedIds, + true ); + } + DeviceCaps.DevType = DeviceType::OpenGL; + DeviceCaps.MajorVersion = MajorVersion; + DeviceCaps.MinorVersion = MinorVersion; + bool IsGL43OrAbove = MajorVersion >= 5 || MajorVersion == 4 && MinorVersion >= 3; + auto &TexCaps = DeviceCaps.TexCaps; + TexCaps.bTexture2DMSSupported = IsGL43OrAbove; + TexCaps.bTexture2DMSArraySupported = IsGL43OrAbove; + TexCaps.bTextureViewSupported = IsGL43OrAbove; + } + + GLContext::~GLContext() + { + // Do not destroy context if it was create by the app. + if( m_Context ) + { + wglMakeCurrent( m_WindowHandleToDeviceContext, 0 ); + wglDeleteContext( m_Context ); + } + } + + void GLContext::SwapBuffers() + { + ::SwapBuffers( m_WindowHandleToDeviceContext ); + } +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp b/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp new file mode 100644 index 00000000..5793e469 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp @@ -0,0 +1,37 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "GLObjectWrapper.h" + +namespace GLObjectWrappers +{ + const char *GLBufferObjCreateReleaseHelper :: Name = "buffer"; + const char *GLProgramObjCreateReleaseHelper :: Name = "program"; + const char *GLShaderObjCreateReleaseHelper :: Name = "shader"; + const char *GLPipelineObjCreateReleaseHelper:: Name = "piepline"; + const char *GLVAOCreateReleaseHelper :: Name = "vertex array"; + const char *GLTextureCreateReleaseHelper :: Name = "texture"; + const char *GLSamplerCreateReleaseHelper :: Name = "sampler"; + const char *GLFBOCreateReleaseHelper :: Name = "framebuffer"; +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp new file mode 100644 index 00000000..808fcc12 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp @@ -0,0 +1,305 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "GLProgram.h" + +namespace Diligent +{ + GLProgram::GLProgram( bool CreateObject ) : + GLObjectWrappers::GLProgramObj( CreateObject ) + {} + + GLProgram::GLProgram( GLProgram&& Program ): + GLObjectWrappers::GLProgramObj( std::move( Program ) ), + m_UniformBlocks( std::move( Program.m_UniformBlocks ) ), + m_Samplers( std::move( Program.m_Samplers ) ), + m_Images( std::move( Program.m_Images ) ), + m_StorageBlocks( std::move( Program.m_StorageBlocks ) ) + {} + + void GLProgram::LoadUniforms() + { + GLuint GLProgram = static_cast<GLuint>(*this); + + GLint numActiveUniforms = 0; + glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORMS, &numActiveUniforms ); + CHECK_GL_ERROR_AND_THROW( "Unable to get number of active uniforms\n" ); + + // Query the maximum name length of the active uniform (including null terminator) + GLint activeUniformMaxLength = 0; + glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformMaxLength ); + CHECK_GL_ERROR_AND_THROW( "Unable to get maximum uniform name length\n" ); + + GLint numActiveUniformBlocks = 0; + glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numActiveUniformBlocks ); + CHECK_GL_ERROR_AND_THROW( "Unable to get the number of active uniform blocks\n" ); + + // + // #### This parameter is currently unsupported by Intel OGL drivers. + // + // Query the maximum name length of the active uniform block (including null terminator) + GLint activeUniformBlockMaxLength = 0; + // On Intel driver, this call might fail: + glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &activeUniformBlockMaxLength ); + //CHECK_GL_ERROR_AND_THROW("Unable to get the maximum uniform block name length\n"); + if( GL_NO_ERROR != glGetError() ) + { + LOG_WARNING_MESSAGE( "Unable to get the maximum uniform block name length. Using 1024 as a workaround\n" ); + activeUniformBlockMaxLength = 1024; + } + + + GLint numActiveShaderStorageBlocks = 0; + glGetProgramInterfaceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numActiveShaderStorageBlocks ); + CHECK_GL_ERROR_AND_THROW( "Unable to get the number of shader storage blocks blocks\n" ); + + // Query the maximum name length of the active shader storage block (including null terminator) + GLint MaxShaderStorageBlockNameLen = 0; + glGetProgramInterfaceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &MaxShaderStorageBlockNameLen ); + CHECK_GL_ERROR_AND_THROW( "Unable to get the maximum shader storage block name length\n" ); + + auto MaxNameLength = std::max( activeUniformMaxLength, activeUniformBlockMaxLength ); + MaxNameLength = std::max( MaxNameLength, MaxShaderStorageBlockNameLen ); + + MaxNameLength = std::max( MaxNameLength, 512 ); + std::vector<GLchar> Name( MaxNameLength + 1 ); + for( int i = 0; i < numActiveUniforms; i++ ) + { + GLenum dataType = 0; + GLint size = 0; + GLint NameLen = 0; + glGetActiveUniform( GLProgram, i, MaxNameLength, &NameLen, &size, &dataType, Name.data() ); + CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform\n" ); + VERIFY( NameLen < MaxNameLength && NameLen == strlen( Name.data() ), "Incorrect uniform name" ); + // Note that + // glGetActiveUniform( program, index, bufSize, length, size, type, name ); + // + // is equivalent to + // + // const enum props[] = { ARRAY_SIZE, TYPE }; + // glGetProgramResourceName( program, UNIFORM, index, bufSize, length, name ); + // glGetProgramResourceiv( program, GL_UNIFORM, index, 1, &props[0], 1, NULL, size ); + // glGetProgramResourceiv( program, GL_UNIFORM, index, 1, &props[1], 1, NULL, (int *)type ); + // + // The latter is only available in GL 4.4 and GLES 3.1 + + switch( dataType ) + { + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D_SHADOW: + + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_1D_ARRAY_SHADOW: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_CUBE_SHADOW: + + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_CUBE: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + + case GL_SAMPLER_CUBE_MAP_ARRAY: + case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: + case GL_INT_SAMPLER_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: + + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + + case GL_SAMPLER_BUFFER: + case GL_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + { + auto UniformLocation = glGetUniformLocation( GLProgram, Name.data() ); + // Note that glGetUniformLocation(program, name) is equivalent to + // glGetProgramResourceLocation( program, GL_UNIFORM, name ); + // The latter is only available in GL 4.4 and GLES 3.1 + m_Samplers.emplace_back( SamplerInfo( Name.data(), UniformLocation, dataType) ); + break; + } + + case GL_IMAGE_1D: + case GL_IMAGE_2D: + case GL_IMAGE_3D: + case GL_IMAGE_2D_RECT: + case GL_IMAGE_CUBE: + case GL_IMAGE_BUFFER: + case GL_IMAGE_1D_ARRAY: + case GL_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE_MAP_ARRAY: + case GL_IMAGE_2D_MULTISAMPLE: + case GL_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_INT_IMAGE_1D: + case GL_INT_IMAGE_2D: + case GL_INT_IMAGE_3D: + case GL_INT_IMAGE_2D_RECT: + case GL_INT_IMAGE_CUBE: + case GL_INT_IMAGE_BUFFER: + case GL_INT_IMAGE_1D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_INT_IMAGE_2D_MULTISAMPLE: + case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_IMAGE_1D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_2D_RECT: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_BUFFER: + case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: + { + auto UniformLocation = glGetUniformLocation( GLProgram, Name.data() ); + + GLint BindingPoint = -1; + // The value of an image uniform is an integer specifying the image unit accessed + glGetUniformiv( GLProgram, UniformLocation, &BindingPoint ); + CHECK_GL_ERROR_AND_THROW("Failed to get image binding point"); + VERIFY( BindingPoint >= 0, "Incorrect binding point" ); + + m_Images.emplace_back( ImageInfo(Name.data(), BindingPoint, dataType) ); + break; + } + + default: + // Some other uniform type like scalar, matrix etc. + break; + } + } + + for( int i = 0; i < numActiveUniformBlocks; i++ ) + { + GLsizei NameLen = 0; + glGetActiveUniformBlockName( GLProgram, i, MaxNameLength, &NameLen, Name.data() ); + CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform block name\n" ); + VERIFY( NameLen < MaxNameLength && NameLen == strlen( Name.data() ), "Incorrect uniform block name" ); + + // glGetActiveUniformBlockName( program, uniformBlockIndex, bufSize, length, uniformBlockName ); + // is equivalent to + // glGetProgramResourceName(program, GL_UNIFORM_BLOCK, uniformBlockIndex, bufSize, length, uniformBlockName); + + auto UniformBlockIndex = glGetUniformBlockIndex( GLProgram, Name.data() ); + CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform block index\n" ); + // glGetUniformBlockIndex( program, uniformBlockName ); + // is equivalent to + // glGetProgramResourceIndex( program, GL_UNIFORM_BLOCK, uniformBlockName ); + m_UniformBlocks.emplace_back(UniformBufferInfo(Name.data(), UniformBlockIndex)); + } + + for( int i = 0; i < numActiveShaderStorageBlocks; ++i ) + { + GLsizei Length = 0; + glGetProgramResourceName( GLProgram, GL_SHADER_STORAGE_BLOCK, i, MaxNameLength, &Length, Name.data() ); + CHECK_GL_ERROR_AND_THROW( "Unable to get shader storage block name\n" ); + VERIFY( Length < MaxNameLength && Length == strlen( Name.data() ), "Incorrect shader storage block name" ); + + GLenum Prop = GL_BUFFER_BINDING; + GLint Binding = -1; + GLint ValuesWritten = 0; + glGetProgramResourceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, i, 1, &Prop, 1, &ValuesWritten, &Binding ); + CHECK_GL_ERROR_AND_THROW( "Unable to get shader storage block binding\n" ); + VERIFY( ValuesWritten == 1 && Binding >= 0, "Incorrect shader storage block binding" ); + + m_StorageBlocks.emplace_back( StorageBlockInfo(Name.data(), Binding) ); + } + } + + template<typename TResArrayType> + void BindResourcesHelper(TResArrayType &ResArr, IResourceMapping *pResourceMapping, Uint32 Flags) + { + for( auto res = ResArr.begin(); res != ResArr.end(); ++res ) + { + auto &Name = res->Name; + if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) + res->pResource.Release(); + + if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && res->pResource ) + continue; // Skip already resolved resources + + RefCntAutoPtr<IDeviceObject> pNewRes; + pResourceMapping->GetResource( Name.c_str(), static_cast<IDeviceObject**>(&pNewRes) ); + + if( !pNewRes ) + { + if( Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED ) + LOG_ERROR_MESSAGE( "Resource \"", Name, "\" is not found in the resource mapping" ); + continue; + } + res->pResource = pNewRes; + } + } + + void GLProgram::BindResources( IResourceMapping *pResourceMapping, Uint32 Flags ) + { + if( !pResourceMapping ) + return; + + BindResourcesHelper( m_UniformBlocks, pResourceMapping, Flags ); + BindResourcesHelper( m_Samplers, pResourceMapping, Flags ); + BindResourcesHelper( m_Images, pResourceMapping, Flags ); + BindResourcesHelper( m_StorageBlocks, pResourceMapping, Flags ); + } + +#ifdef VERIFY_RESOURCE_BINDINGS + template<typename TResArrayType> + void dbgVerifyResourceBindingsHelper(TResArrayType &ResArr, const Char *VarType) + { + for( auto res = ResArr.begin(); res != ResArr.end(); ++res ) + { + auto &Name = res->Name; + if( !res->pResource ) + LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", res->Name, "\"" ); + } + } + + void GLProgram::dbgVerifyResourceBindings() + { + dbgVerifyResourceBindingsHelper( m_UniformBlocks, "uniform block" ); + dbgVerifyResourceBindingsHelper( m_Samplers, "sampler" ); + dbgVerifyResourceBindingsHelper( m_Images, "image" ); + dbgVerifyResourceBindingsHelper( m_StorageBlocks, "shader storage block" ); + } +#endif + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GLStubs.cpp b/Graphics/GraphicsEngineOpenGL/src/GLStubs.cpp new file mode 100644 index 00000000..d200bc33 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GLStubs.cpp @@ -0,0 +1,266 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "GLStubs.h" +#include <EGL/egl.h> + +#define DECLARE_GL_FUNCTION(Func, FuncType, ...)\ + FuncType Func = nullptr; \ + void Func##Stub(__VA_ARGS__) \ + { \ + UnsupportedGLFunctionStub(#Func); \ + } + +#ifdef LOAD_GL_BIND_IMAGE_TEXTURE + DECLARE_GL_FUNCTION( glBindImageTexture, PFNGLBINDIMAGETEXTUREPROC, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format ) +#endif + +#ifdef LOAD_GL_DISPATCH_COMPUTE + DECLARE_GL_FUNCTION( glDispatchCompute, PFNGLDISPATCHCOMPUTEPROC, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z ) +#endif + +#ifdef LOAD_GL_PROGRAM_UNIFORM_1I + DECLARE_GL_FUNCTION( glProgramUniform1i, PFNGLPROGRAMUNIFORM1IPROC, GLuint program, GLint location, GLint x ) +#endif + +#ifdef LOAD_GL_MEMORY_BARRIER + DECLARE_GL_FUNCTION( glMemoryBarrier, PFNGLMEMORYBARRIERPROC, GLbitfield barriers ) +#endif + +#ifdef LOAD_DRAW_ELEMENTS_INDIRECT + DECLARE_GL_FUNCTION( glDrawElementsIndirect, PFNGLDRAWELEMENTSINDIRECTPROC, GLenum mode, GLenum type, const GLvoid *indirect ) +#endif + +#ifdef LOAD_DRAW_ARRAYS_INDIRECT + DECLARE_GL_FUNCTION( glDrawArraysIndirect, PFNGLDRAWARRAYSINDIRECTPROC, GLenum mode, const GLvoid *indirect ) +#endif + +#ifdef LOAD_GEN_PROGRAM_PIPELINES + DECLARE_GL_FUNCTION( glGenProgramPipelines, PFNGLGENPROGRAMPIPELINESPROC, GLsizei n, GLuint* pipelines ) +#endif + +#ifdef LOAD_GL_DELETE_PROGRAM_PIPELINES + DECLARE_GL_FUNCTION( glDeleteProgramPipelines, PFNGLDELETEPROGRAMPIPELINESPROC, GLsizei n, const GLuint* pipelines ) +#endif + +#ifdef LOAD_GL_BIND_PROGRAM_PIPELINE + DECLARE_GL_FUNCTION( glBindProgramPipeline, PFNGLBINDPROGRAMPIPELINEPROC, GLuint pipeline ) +#endif + +#ifdef LOAD_GL_USE_PROGRAM_STAGES + DECLARE_GL_FUNCTION( glUseProgramStages, PFNGLUSEPROGRAMSTAGESPROC, GLuint pipeline, GLbitfield stages, GLuint program ) +#endif + +#ifdef LOAD_GL_TEX_STORAGE_2D_MULTISAMPLE + DECLARE_GL_FUNCTION( glTexStorage2DMultisample, PFNGLTEXSTORAGE2DMULTISAMPLEPROC, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations ) +#endif + +#ifdef LOAD_GL_GET_PROGRAM_INTERFACEIV + DECLARE_GL_FUNCTION( glGetProgramInterfaceiv, PFNGLGETPROGRAMINTERFACEIVPROC, GLuint program, GLenum programInterface, GLenum pname, GLint* params ) +#endif + +#ifdef LOAD_GL_GET_PROGRAM_RESOURCE_NAME + DECLARE_GL_FUNCTION( glGetProgramResourceName, PFNGLGETPROGRAMRESOURCENAMEPROC, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar *name ) +#endif + +#ifdef LOAD_GL_GET_PROGRAM_RESOURCEIV + DECLARE_GL_FUNCTION( glGetProgramResourceiv, PFNGLGETPROGRAMRESOURCEIVPROC, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLint *params ) +#endif + +#ifdef LOAD_DISPATCH_COMPUTE_INDIRECT + DECLARE_GL_FUNCTION( glDispatchComputeIndirect, PFNGLDISPATCHCOMPUTEINDIRECTPROC, GLintptr indirect ) +#endif + +#ifdef LOAD_GL_TEX_BUFFER + DECLARE_GL_FUNCTION( glTexBuffer, PFNGLTEXBUFFERPROC, GLenum, GLenum, GLuint) +#endif + +#ifdef LOAD_GL_POLYGON_MODE + DECLARE_GL_FUNCTION( glPolygonMode, PFNGLPOLYGONMODE, GLenum, GLenum) +#endif + +#ifdef LOAD_GL_ENABLEI + DECLARE_GL_FUNCTION( glEnablei, PFNGLENABLEIPROC, GLenum, GLuint) +#endif + +#ifdef LOAD_GL_BLEND_FUNC_SEPARATEI + DECLARE_GL_FUNCTION( glBlendFuncSeparatei, PFNGLBLENDFUNCSEPARATEIPROC, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +#endif + +#ifdef LOAD_GL_BLEND_EQUATION_SEPARATEI + DECLARE_GL_FUNCTION( glBlendEquationSeparatei, PFNGLBLENDEQUATIONSEPARATEIPROC, GLuint buf, GLenum modeRGB, GLenum modeAlpha) +#endif + +#ifdef LOAD_GL_DISABLEI + DECLARE_GL_FUNCTION( glDisablei, PFNGLDISABLEIPROC, GLenum, GLuint) +#endif + +#ifdef LOAD_GL_COLOR_MASKI + DECLARE_GL_FUNCTION( glColorMaski, PFNGLCOLORMASKIPROC, GLuint, GLboolean, GLboolean, GLboolean, GLboolean) +#endif + +#ifdef LOAD_GL_VIEWPORT_INDEXEDF + DECLARE_GL_FUNCTION( glViewportIndexedf, PFNGLVIEWPORTINDEXEDFPROC, GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h) +#endif + +#ifdef LOAD_GL_SCISSOR_INDEXED + DECLARE_GL_FUNCTION( glScissorIndexed, PFNGLSCISSORINDEXEDPROC, GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height) +#endif + +#ifdef LOAD_GL_FRAMEBUFFER_TEXTURE + DECLARE_GL_FUNCTION( glFramebufferTexture, PFNGLFRAMEBUFFERTEXTUREPROC, GLenum, GLenum, GLuint, GLint) +#endif + +#ifdef LOAD_GL_FRAMEBUFFER_TEXTURE_1D + DECLARE_GL_FUNCTION( glFramebufferTexture1D, PFNGLFRAMEBUFFERTEXTURE1DPROC, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +#endif + +#ifdef LOAD_GL_FRAMEBUFFER_TEXTURE_3D + DECLARE_GL_FUNCTION( glFramebufferTexture3D, PFNGLFRAMEBUFFERTEXTURE3DPROC, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer ) +#endif + +#ifdef LOAD_GL_COPY_IMAGE_SUB_DATA + DECLARE_GL_FUNCTION( glCopyImageSubData, PFNGLCOPYIMAGESUBDATAPROC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth ) +#endif + +void LoadGLFunctions() +{ + +#define LOAD_GL_FUNCTION(Func, FuncType)\ +Func = (FuncType)eglGetProcAddress( #Func );\ + if( !Func )Func = Func##Stub; + +#ifdef LOAD_GL_BIND_IMAGE_TEXTURE + LOAD_GL_FUNCTION( glBindImageTexture, PFNGLBINDIMAGETEXTUREPROC ) +#endif + +#ifdef LOAD_GL_DISPATCH_COMPUTE + LOAD_GL_FUNCTION( glDispatchCompute, PFNGLDISPATCHCOMPUTEPROC ) +#endif + +#ifdef LOAD_GEN_PROGRAM_PIPELINES + LOAD_GL_FUNCTION( glGenProgramPipelines, PFNGLGENPROGRAMPIPELINESPROC ) +#endif + +#ifdef LOAD_GL_DELETE_PROGRAM_PIPELINES + LOAD_GL_FUNCTION( glDeleteProgramPipelines, PFNGLDELETEPROGRAMPIPELINESPROC ) +#endif + +#ifdef LOAD_GL_BIND_PROGRAM_PIPELINE + LOAD_GL_FUNCTION( glBindProgramPipeline, PFNGLBINDPROGRAMPIPELINEPROC ) +#endif + +#ifdef LOAD_GL_USE_PROGRAM_STAGES + LOAD_GL_FUNCTION( glUseProgramStages, PFNGLUSEPROGRAMSTAGESPROC ) +#endif + +#ifdef LOAD_GL_PROGRAM_UNIFORM_1I + LOAD_GL_FUNCTION( glProgramUniform1i, PFNGLPROGRAMUNIFORM1IPROC ) +#endif + +#ifdef LOAD_GL_MEMORY_BARRIER + LOAD_GL_FUNCTION( glMemoryBarrier, PFNGLMEMORYBARRIERPROC ) +#endif + +#ifdef LOAD_DRAW_ELEMENTS_INDIRECT + LOAD_GL_FUNCTION( glDrawElementsIndirect, PFNGLDRAWELEMENTSINDIRECTPROC ) +#endif + +#ifdef LOAD_DRAW_ARRAYS_INDIRECT + LOAD_GL_FUNCTION( glDrawArraysIndirect, PFNGLDRAWARRAYSINDIRECTPROC ) +#endif + +#ifdef LOAD_GL_TEX_STORAGE_2D_MULTISAMPLE + LOAD_GL_FUNCTION( glTexStorage2DMultisample, PFNGLTEXSTORAGE2DMULTISAMPLEPROC ) +#endif + +#ifdef LOAD_GL_GET_PROGRAM_INTERFACEIV + LOAD_GL_FUNCTION( glGetProgramInterfaceiv, PFNGLGETPROGRAMINTERFACEIVPROC ) +#endif + +#ifdef LOAD_GL_GET_PROGRAM_RESOURCE_NAME + LOAD_GL_FUNCTION( glGetProgramResourceName, PFNGLGETPROGRAMRESOURCENAMEPROC ) +#endif + +#ifdef LOAD_GL_GET_PROGRAM_RESOURCEIV + LOAD_GL_FUNCTION( glGetProgramResourceiv, PFNGLGETPROGRAMRESOURCEIVPROC ) +#endif + +#ifdef LOAD_DISPATCH_COMPUTE_INDIRECT + LOAD_GL_FUNCTION( glDispatchComputeIndirect, PFNGLDISPATCHCOMPUTEINDIRECTPROC ) +#endif + +#ifdef LOAD_GL_TEX_BUFFER + LOAD_GL_FUNCTION( glTexBuffer, PFNGLTEXBUFFERPROC ) +#endif + +#ifdef LOAD_GL_POLYGON_MODE + LOAD_GL_FUNCTION( glPolygonMode, PFNGLPOLYGONMODE) +#endif + +#ifdef LOAD_GL_ENABLEI + LOAD_GL_FUNCTION( glEnablei, PFNGLENABLEIPROC) +#endif + +#ifdef LOAD_GL_BLEND_FUNC_SEPARATEI + LOAD_GL_FUNCTION( glBlendFuncSeparatei, PFNGLBLENDFUNCSEPARATEIPROC ) +#endif + +#ifdef LOAD_GL_BLEND_EQUATION_SEPARATEI + LOAD_GL_FUNCTION( glBlendEquationSeparatei, PFNGLBLENDEQUATIONSEPARATEIPROC ) +#endif + +#ifdef LOAD_GL_DISABLEI + LOAD_GL_FUNCTION( glDisablei, PFNGLDISABLEIPROC ) +#endif + +#ifdef LOAD_GL_COLOR_MASKI + LOAD_GL_FUNCTION( glColorMaski, PFNGLCOLORMASKIPROC ) +#endif + +#ifdef LOAD_GL_VIEWPORT_INDEXEDF + LOAD_GL_FUNCTION( glViewportIndexedf, PFNGLVIEWPORTINDEXEDFPROC ) +#endif + +#ifdef LOAD_GL_SCISSOR_INDEXED + LOAD_GL_FUNCTION( glScissorIndexed, PFNGLSCISSORINDEXEDPROC ) +#endif + +#ifdef LOAD_GL_FRAMEBUFFER_TEXTURE + LOAD_GL_FUNCTION( glFramebufferTexture, PFNGLFRAMEBUFFERTEXTUREPROC ) +#endif + +#ifdef LOAD_GL_FRAMEBUFFER_TEXTURE_1D + LOAD_GL_FUNCTION( glFramebufferTexture1D, PFNGLFRAMEBUFFERTEXTURE1DPROC ) +#endif + +#ifdef LOAD_GL_FRAMEBUFFER_TEXTURE_3D + LOAD_GL_FUNCTION( glFramebufferTexture3D, PFNGLFRAMEBUFFERTEXTURE3DPROC ) +#endif + +#ifdef LOAD_GL_COPY_IMAGE_SUB_DATA + // Do not use proxy if function is not available! + glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)eglGetProcAddress( "glCopyImageSubData" ); +#endif +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp b/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp new file mode 100644 index 00000000..27e3e81a --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp @@ -0,0 +1,602 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "GLTypeConversions.h" + +namespace Diligent +{ + + +GLenum TexFormatToGLInternalTexFormat(TEXTURE_FORMAT TexFormat, Uint32 BindFlags) +{ + static Bool bFormatMapIntialized = false; + static GLenum FmtToGLFmtMap[TEX_FORMAT_NUM_FORMATS] = {0}; + if( !bFormatMapIntialized ) + { + // http://www.opengl.org/wiki/Image_Format + FmtToGLFmtMap[ TEX_FORMAT_UNKNOWN ] = 0; + + FmtToGLFmtMap[ TEX_FORMAT_RGBA32_TYPELESS ] = GL_RGBA32F; + FmtToGLFmtMap[ TEX_FORMAT_RGBA32_FLOAT ] = GL_RGBA32F; + FmtToGLFmtMap[ TEX_FORMAT_RGBA32_UINT ] = GL_RGBA32UI; + FmtToGLFmtMap[ TEX_FORMAT_RGBA32_SINT ] = GL_RGBA32I; + + FmtToGLFmtMap[ TEX_FORMAT_RGB32_TYPELESS ] = GL_RGB32F; + FmtToGLFmtMap[ TEX_FORMAT_RGB32_FLOAT ] = GL_RGB32F; + FmtToGLFmtMap[ TEX_FORMAT_RGB32_UINT ] = GL_RGB32UI; + FmtToGLFmtMap[ TEX_FORMAT_RGB32_SINT ] = GL_RGB32I; + + FmtToGLFmtMap[ TEX_FORMAT_RGBA16_TYPELESS ] = GL_RGBA16F; + FmtToGLFmtMap[ TEX_FORMAT_RGBA16_FLOAT ] = GL_RGBA16F; + FmtToGLFmtMap[ TEX_FORMAT_RGBA16_UNORM ] = GL_RGBA16; + FmtToGLFmtMap[ TEX_FORMAT_RGBA16_UINT ] = GL_RGBA16UI; + FmtToGLFmtMap[ TEX_FORMAT_RGBA16_SNORM ] = GL_RGBA16_SNORM; + FmtToGLFmtMap[ TEX_FORMAT_RGBA16_SINT ] = GL_RGBA16I; + + FmtToGLFmtMap[ TEX_FORMAT_RG32_TYPELESS ] = GL_RG32F; + FmtToGLFmtMap[ TEX_FORMAT_RG32_FLOAT ] = GL_RG32F; + FmtToGLFmtMap[ TEX_FORMAT_RG32_UINT ] = GL_RG32UI; + FmtToGLFmtMap[ TEX_FORMAT_RG32_SINT ] = GL_RG32I; + + FmtToGLFmtMap[ TEX_FORMAT_R32G8X24_TYPELESS ] = GL_DEPTH32F_STENCIL8; + FmtToGLFmtMap[ TEX_FORMAT_D32_FLOAT_S8X24_UINT ] = GL_DEPTH32F_STENCIL8; + FmtToGLFmtMap[ TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS ]=GL_DEPTH32F_STENCIL8; + FmtToGLFmtMap[ TEX_FORMAT_X32_TYPELESS_G8X24_UINT ]= 0;//GL_DEPTH32F_STENCIL8; + + FmtToGLFmtMap[ TEX_FORMAT_RGB10A2_TYPELESS ] = GL_RGB10_A2; + FmtToGLFmtMap[ TEX_FORMAT_RGB10A2_UNORM ] = GL_RGB10_A2; + FmtToGLFmtMap[ TEX_FORMAT_RGB10A2_UINT ] = GL_RGB10_A2UI; + FmtToGLFmtMap[ TEX_FORMAT_R11G11B10_FLOAT ] = GL_R11F_G11F_B10F; + + FmtToGLFmtMap[ TEX_FORMAT_RGBA8_TYPELESS ] = GL_RGBA8; + FmtToGLFmtMap[ TEX_FORMAT_RGBA8_UNORM ] = GL_RGBA8; + FmtToGLFmtMap[ TEX_FORMAT_RGBA8_UNORM_SRGB ] = GL_SRGB8_ALPHA8; + FmtToGLFmtMap[ TEX_FORMAT_RGBA8_UINT ] = GL_RGBA8UI; + FmtToGLFmtMap[ TEX_FORMAT_RGBA8_SNORM ] = GL_RGBA8_SNORM; + FmtToGLFmtMap[ TEX_FORMAT_RGBA8_SINT ] = GL_RGBA8I; + + FmtToGLFmtMap[ TEX_FORMAT_RG16_TYPELESS ] = GL_RG16F; + FmtToGLFmtMap[ TEX_FORMAT_RG16_FLOAT ] = GL_RG16F; + FmtToGLFmtMap[ TEX_FORMAT_RG16_UNORM ] = GL_RG16; + FmtToGLFmtMap[ TEX_FORMAT_RG16_UINT ] = GL_RG16UI; + FmtToGLFmtMap[ TEX_FORMAT_RG16_SNORM ] = GL_RG16_SNORM; + FmtToGLFmtMap[ TEX_FORMAT_RG16_SINT ] = GL_RG16I; + + FmtToGLFmtMap[ TEX_FORMAT_R32_TYPELESS ] = GL_R32F; + FmtToGLFmtMap[ TEX_FORMAT_D32_FLOAT ] = GL_DEPTH_COMPONENT32F; + FmtToGLFmtMap[ TEX_FORMAT_R32_FLOAT ] = GL_R32F; + FmtToGLFmtMap[ TEX_FORMAT_R32_UINT ] = GL_R32UI; + FmtToGLFmtMap[ TEX_FORMAT_R32_SINT ] = GL_R32I; + + FmtToGLFmtMap[ TEX_FORMAT_R24G8_TYPELESS ] = GL_DEPTH24_STENCIL8; + FmtToGLFmtMap[ TEX_FORMAT_D24_UNORM_S8_UINT ] = GL_DEPTH24_STENCIL8; + FmtToGLFmtMap[ TEX_FORMAT_R24_UNORM_X8_TYPELESS ] = GL_DEPTH24_STENCIL8; + FmtToGLFmtMap[ TEX_FORMAT_X24_TYPELESS_G8_UINT ] = 0;//GL_DEPTH24_STENCIL8; + + FmtToGLFmtMap[ TEX_FORMAT_RG8_TYPELESS ] = GL_RG8; + FmtToGLFmtMap[ TEX_FORMAT_RG8_UNORM ] = GL_RG8; + FmtToGLFmtMap[ TEX_FORMAT_RG8_UINT ] = GL_RG8UI; + FmtToGLFmtMap[ TEX_FORMAT_RG8_SNORM ] = GL_RG8_SNORM; + FmtToGLFmtMap[ TEX_FORMAT_RG8_SINT ] = GL_RG8I; + + FmtToGLFmtMap[ TEX_FORMAT_R16_TYPELESS ] = GL_R16F; + FmtToGLFmtMap[ TEX_FORMAT_R16_FLOAT ] = GL_R16F; + FmtToGLFmtMap[ TEX_FORMAT_D16_UNORM ] = GL_DEPTH_COMPONENT16; + FmtToGLFmtMap[ TEX_FORMAT_R16_UNORM ] = GL_R16; + FmtToGLFmtMap[ TEX_FORMAT_R16_UINT ] = GL_R16UI; + FmtToGLFmtMap[ TEX_FORMAT_R16_SNORM ] = GL_R16_SNORM; + FmtToGLFmtMap[ TEX_FORMAT_R16_SINT ] = GL_R16I; + + FmtToGLFmtMap[ TEX_FORMAT_R8_TYPELESS ] = GL_R8; + FmtToGLFmtMap[ TEX_FORMAT_R8_UNORM ] = GL_R8; + FmtToGLFmtMap[ TEX_FORMAT_R8_UINT ] = GL_R8UI; + FmtToGLFmtMap[ TEX_FORMAT_R8_SNORM ] = GL_R8_SNORM; + FmtToGLFmtMap[ TEX_FORMAT_R8_SINT ] = GL_R8I; + FmtToGLFmtMap[ TEX_FORMAT_A8_UNORM ] = 0; + + FmtToGLFmtMap[ TEX_FORMAT_R1_UNORM ] = 0; + + FmtToGLFmtMap[ TEX_FORMAT_RGB9E5_SHAREDEXP ] = GL_RGB9_E5; + FmtToGLFmtMap[ TEX_FORMAT_RG8_B8G8_UNORM ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_G8R8_G8B8_UNORM ] = 0; + + // http://www.g-truc.net/post-0335.html + // http://renderingpipeline.com/2012/07/texture-compression/ + FmtToGLFmtMap[ TEX_FORMAT_BC1_TYPELESS ] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC1_UNORM ] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC1_UNORM_SRGB ] = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC2_TYPELESS ] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC2_UNORM ] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC2_UNORM_SRGB ] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC3_TYPELESS ] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC3_UNORM ] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC3_UNORM_SRGB ] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + FmtToGLFmtMap[ TEX_FORMAT_BC4_TYPELESS ] = GL_COMPRESSED_RED_RGTC1; + FmtToGLFmtMap[ TEX_FORMAT_BC4_UNORM ] = GL_COMPRESSED_RED_RGTC1; + FmtToGLFmtMap[ TEX_FORMAT_BC4_SNORM ] = GL_COMPRESSED_SIGNED_RED_RGTC1; + FmtToGLFmtMap[ TEX_FORMAT_BC5_TYPELESS ] = GL_COMPRESSED_RG_RGTC2; + FmtToGLFmtMap[ TEX_FORMAT_BC5_UNORM ] = GL_COMPRESSED_RG_RGTC2; + FmtToGLFmtMap[ TEX_FORMAT_BC5_SNORM ] = GL_COMPRESSED_SIGNED_RG_RGTC2; + FmtToGLFmtMap[ TEX_FORMAT_B5G6R5_UNORM ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_B5G5R5A1_UNORM ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_BGRA8_UNORM ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_BGRX8_UNORM ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_BGRA8_TYPELESS ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_BGRA8_UNORM_SRGB ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_BGRX8_TYPELESS ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_BGRX8_UNORM_SRGB ] = 0; + FmtToGLFmtMap[ TEX_FORMAT_BC6H_TYPELESS ] = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + FmtToGLFmtMap[ TEX_FORMAT_BC6H_UF16 ] = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + FmtToGLFmtMap[ TEX_FORMAT_BC6H_SF16 ] = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT; + FmtToGLFmtMap[ TEX_FORMAT_BC7_TYPELESS ] = GL_COMPRESSED_RGBA_BPTC_UNORM; + FmtToGLFmtMap[ TEX_FORMAT_BC7_UNORM ] = GL_COMPRESSED_RGBA_BPTC_UNORM; + FmtToGLFmtMap[ TEX_FORMAT_BC7_UNORM_SRGB ] = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; + + bFormatMapIntialized = true; + } + + if( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS ) + { + auto GLFormat = FmtToGLFmtMap[TexFormat]; + if( BindFlags != 0 ) + GLFormat = CorrectGLTexFormat( GLFormat, BindFlags ); + return GLFormat; + } + else + { + UNEXPECTED( "Texture format (", TexFormat, ") out of allowed range [0, ", TEX_FORMAT_NUM_FORMATS-1, "]" ); + return 0; + } +} + +GLenum CorrectGLTexFormat( GLenum GLTexFormat, Uint32 BindFlags ) +{ + if( BindFlags & BIND_DEPTH_STENCIL ) + { + if( GLTexFormat == GL_R32F ) + GLTexFormat = GL_DEPTH_COMPONENT32F; + if( GLTexFormat == GL_R16 ) + GLTexFormat = GL_DEPTH_COMPONENT16; + } + return GLTexFormat; +} + +NativePixelAttribs GetNativePixelTransferAttribs(TEXTURE_FORMAT TexFormat) +{ + // http://www.opengl.org/wiki/Pixel_Transfer + + static Bool bAttribsMapIntialized = false; + static NativePixelAttribs FmtToGLPixelFmt[TEX_FORMAT_NUM_FORMATS]; + if( !bAttribsMapIntialized) + { + // http://www.opengl.org/wiki/Image_Format + FmtToGLPixelFmt[ TEX_FORMAT_UNKNOWN ] = NativePixelAttribs(); + + FmtToGLPixelFmt[ TEX_FORMAT_RGBA32_TYPELESS ] = NativePixelAttribs(GL_RGBA, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA32_FLOAT ] = NativePixelAttribs(GL_RGBA, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA32_UINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_INT); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA32_SINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_INT); + + FmtToGLPixelFmt[ TEX_FORMAT_RGB32_TYPELESS ] = NativePixelAttribs(GL_RGB, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RGB32_FLOAT ] = NativePixelAttribs(GL_RGB, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RGB32_UINT ] = NativePixelAttribs(GL_RGB_INTEGER, GL_UNSIGNED_INT); + FmtToGLPixelFmt[ TEX_FORMAT_RGB32_SINT ] = NativePixelAttribs(GL_RGB_INTEGER, GL_INT); + + FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_TYPELESS ] = NativePixelAttribs(GL_RGBA, GL_HALF_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_FLOAT ] = NativePixelAttribs(GL_RGBA, GL_HALF_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_UNORM ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_UINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_SNORM ] = NativePixelAttribs(GL_RGBA, GL_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_SINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_SHORT); + + FmtToGLPixelFmt[ TEX_FORMAT_RG32_TYPELESS ] = NativePixelAttribs(GL_RG, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RG32_FLOAT ] = NativePixelAttribs(GL_RG, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RG32_UINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_INT); + FmtToGLPixelFmt[ TEX_FORMAT_RG32_SINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_INT); + + FmtToGLPixelFmt[ TEX_FORMAT_R32G8X24_TYPELESS ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + FmtToGLPixelFmt[ TEX_FORMAT_D32_FLOAT_S8X24_UINT ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + FmtToGLPixelFmt[ TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS ]=NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + FmtToGLPixelFmt[ TEX_FORMAT_X32_TYPELESS_G8X24_UINT ]= NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + + // Components are normally packed with the first component in the most significant + // bits of the bitfield, and successive component occupying progressively less + // significant locations.Types whose token names end with _REV reverse the component + // packing order from least to most significant locations. + FmtToGLPixelFmt[ TEX_FORMAT_RGB10A2_TYPELESS ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV); + FmtToGLPixelFmt[ TEX_FORMAT_RGB10A2_UNORM ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV); + FmtToGLPixelFmt[ TEX_FORMAT_RGB10A2_UINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV); + FmtToGLPixelFmt[ TEX_FORMAT_R11G11B10_FLOAT ] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV); + + FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_TYPELESS ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_UNORM ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_UNORM_SRGB ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_UINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_SNORM ] = NativePixelAttribs(GL_RGBA, GL_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_SINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_BYTE); + + FmtToGLPixelFmt[ TEX_FORMAT_RG16_TYPELESS ] = NativePixelAttribs(GL_RG, GL_HALF_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RG16_FLOAT ] = NativePixelAttribs(GL_RG, GL_HALF_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_RG16_UNORM ] = NativePixelAttribs(GL_RG, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_RG16_UINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_RG16_SNORM ] = NativePixelAttribs(GL_RG, GL_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_RG16_SINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_SHORT); + + FmtToGLPixelFmt[ TEX_FORMAT_R32_TYPELESS ] = NativePixelAttribs(GL_RED, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_D32_FLOAT ] = NativePixelAttribs(GL_DEPTH_COMPONENT, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_R32_FLOAT ] = NativePixelAttribs(GL_RED, GL_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_R32_UINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_INT); + FmtToGLPixelFmt[ TEX_FORMAT_R32_SINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_INT); + + FmtToGLPixelFmt[ TEX_FORMAT_R24G8_TYPELESS ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + FmtToGLPixelFmt[ TEX_FORMAT_D24_UNORM_S8_UINT ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + FmtToGLPixelFmt[ TEX_FORMAT_R24_UNORM_X8_TYPELESS ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + FmtToGLPixelFmt[ TEX_FORMAT_X24_TYPELESS_G8_UINT ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + + FmtToGLPixelFmt[ TEX_FORMAT_RG8_TYPELESS ] = NativePixelAttribs(GL_RG, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RG8_UNORM ] = NativePixelAttribs(GL_RG, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RG8_UINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RG8_SNORM ] = NativePixelAttribs(GL_RG, GL_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_RG8_SINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_BYTE); + + FmtToGLPixelFmt[ TEX_FORMAT_R16_TYPELESS ] = NativePixelAttribs(GL_RED, GL_HALF_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_R16_FLOAT ] = NativePixelAttribs(GL_RED, GL_HALF_FLOAT); + FmtToGLPixelFmt[ TEX_FORMAT_D16_UNORM ] = NativePixelAttribs(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_R16_UNORM ] = NativePixelAttribs(GL_RED, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_R16_UINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_R16_SNORM ] = NativePixelAttribs(GL_RED, GL_SHORT); + FmtToGLPixelFmt[ TEX_FORMAT_R16_SINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_SHORT); + + FmtToGLPixelFmt[ TEX_FORMAT_R8_TYPELESS ] = NativePixelAttribs(GL_RED, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_R8_UNORM ] = NativePixelAttribs(GL_RED, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_R8_UINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_R8_SNORM ] = NativePixelAttribs(GL_RED, GL_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_R8_SINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_BYTE); + FmtToGLPixelFmt[ TEX_FORMAT_A8_UNORM ] = NativePixelAttribs(); + + FmtToGLPixelFmt[ TEX_FORMAT_R1_UNORM ] = NativePixelAttribs(); + + FmtToGLPixelFmt[ TEX_FORMAT_RGB9E5_SHAREDEXP ] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV); + FmtToGLPixelFmt[ TEX_FORMAT_RG8_B8G8_UNORM ] = NativePixelAttribs(); + FmtToGLPixelFmt[ TEX_FORMAT_G8R8_G8B8_UNORM ] = NativePixelAttribs(); + + // http://www.g-truc.net/post-0335.html + // http://renderingpipeline.com/2012/07/texture-compression/ + FmtToGLPixelFmt[ TEX_FORMAT_BC1_TYPELESS ] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC1_UNORM ] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC1_UNORM_SRGB ] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC2_TYPELESS ] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC2_UNORM ] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC2_UNORM_SRGB ] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC3_TYPELESS ] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC3_UNORM ] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC3_UNORM_SRGB ] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC4_TYPELESS ] = NativePixelAttribs(GL_RED, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC4_UNORM ] = NativePixelAttribs(GL_RED, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC4_SNORM ] = NativePixelAttribs(GL_RED, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC5_TYPELESS ] = NativePixelAttribs(GL_RG, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC5_UNORM ] = NativePixelAttribs(GL_RG, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC5_SNORM ] = NativePixelAttribs(GL_RG, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_B5G6R5_UNORM ] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV); + FmtToGLPixelFmt[ TEX_FORMAT_B5G5R5A1_UNORM ] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_SHORT_1_5_5_5_REV); + FmtToGLPixelFmt[ TEX_FORMAT_BGRA8_UNORM ] = NativePixelAttribs(); + FmtToGLPixelFmt[ TEX_FORMAT_BGRX8_UNORM ] = NativePixelAttribs(); + FmtToGLPixelFmt[ TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ] = NativePixelAttribs(); + FmtToGLPixelFmt[ TEX_FORMAT_BGRA8_TYPELESS ] = NativePixelAttribs(); + FmtToGLPixelFmt[ TEX_FORMAT_BGRA8_UNORM_SRGB ] = NativePixelAttribs(); + FmtToGLPixelFmt[ TEX_FORMAT_BGRX8_TYPELESS ] = NativePixelAttribs(); + FmtToGLPixelFmt[ TEX_FORMAT_BGRX8_UNORM_SRGB ] = NativePixelAttribs(); + FmtToGLPixelFmt[ TEX_FORMAT_BC6H_TYPELESS ] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC6H_UF16 ] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC6H_SF16 ] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC7_TYPELESS ] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC7_UNORM ] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[ TEX_FORMAT_BC7_UNORM_SRGB ] = NativePixelAttribs(GL_RGBA, 0, True); + + bAttribsMapIntialized = true; + } + + if( TexFormat > TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS ) + { + return FmtToGLPixelFmt[TexFormat]; + } + else + { + UNEXPECTED( "Texture format (", TexFormat, ") is out of allowed range [1, ", TEX_FORMAT_NUM_FORMATS-1, "]" ); + return FmtToGLPixelFmt[0]; + } +} + +GLenum AccessFlags2GLAccess( Uint32 UAVAccessFlags ) +{ + static GLenum AccessFlags2GLAccessMap[UAV_ACCESS_FLAG_READ_WRITE + 1] = {}; + static bool bIsInit = false; + if( !bIsInit ) + { + AccessFlags2GLAccessMap[UAV_ACCESS_FLAG_READ] = GL_READ_ONLY; + AccessFlags2GLAccessMap[UAV_ACCESS_FLAG_WRITE] = GL_WRITE_ONLY; + AccessFlags2GLAccessMap[UAV_ACCESS_FLAG_READ_WRITE] = GL_READ_WRITE; + bIsInit = true; + } + + auto GLAccess = AccessFlags2GLAccessMap[UAVAccessFlags & UAV_ACCESS_FLAG_READ_WRITE]; + return GLAccess; +} + + +GLenum TypeToGLTexFormat( VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized ) +{ + switch( ValType ) + { + case VT_FLOAT16: + { + VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); + switch( NumComponents ) + { + case 1: return GL_R16F; + case 2: return GL_RG16F; + case 4: return GL_RGBA16F; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + + case VT_FLOAT32: + { + VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); + switch( NumComponents ) + { + case 1: return GL_R32F; + case 2: return GL_RG32F; + case 3: return GL_RGB32F; + case 4: return GL_RGBA32F; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + + case VT_INT32: + { + VERIFY( !bIsNormalized , "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); + switch( NumComponents ) + { + case 1: return GL_R32I; + case 2: return GL_RG32I; + case 3: return GL_RGB32I; + case 4: return GL_RGBA32I; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + + case VT_UINT32: + { + VERIFY( !bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); + switch( NumComponents ) + { + case 1: return GL_R32UI; + case 2: return GL_RG32UI; + case 3: return GL_RGB32UI; + case 4: return GL_RGBA32UI; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + + case VT_INT16: + { + if( bIsNormalized ) + { + switch( NumComponents ) + { + case 1: return GL_R16_SNORM; + case 2: return GL_RG16_SNORM; + case 4: return GL_RGBA16_SNORM; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + else + { + switch( NumComponents ) + { + case 1: return GL_R16I; + case 2: return GL_RG16I; + case 4: return GL_RGBA16I; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + } + + case VT_UINT16: + { + if( bIsNormalized ) + { + switch( NumComponents ) + { + case 1: return GL_R16; + case 2: return GL_RG16; + case 4: return GL_RGBA16; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + else + { + switch( NumComponents ) + { + case 1: return GL_R16UI; + case 2: return GL_RG16UI; + case 4: return GL_RGBA16UI; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + } + + case VT_INT8: + { + if( bIsNormalized ) + { + switch( NumComponents ) + { + case 1: return GL_R8_SNORM; + case 2: return GL_RG8_SNORM; + case 4: return GL_RGBA8_SNORM; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + else + { + switch( NumComponents ) + { + case 1: return GL_R8I; + case 2: return GL_RG8I; + case 4: return GL_RGBA8I; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + } + + case VT_UINT8: + { + if( bIsNormalized ) + { + switch( NumComponents ) + { + case 1: return GL_R8; + case 2: return GL_RG8; + case 4: return GL_RGBA8; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + else + { + switch( NumComponents ) + { + case 1: return GL_R8UI; + case 2: return GL_RG8UI; + case 4: return GL_RGBA8UI; + default: UNEXPECTED( "Unusupported number of components" ); return 0; + } + } + } + + default: UNEXPECTED( "Unusupported format" ); return 0; + } +} + +GLenum StencilOp2GlStencilOp( STENCIL_OP StencilOp ) +{ + static bool bIsInit = false; + static GLenum GLStencilOps[STENCIL_OP_NUM_OPS] = {}; + if( !bIsInit ) + { + GLStencilOps[STENCIL_OP_KEEP] = GL_KEEP; + GLStencilOps[STENCIL_OP_ZERO] = GL_ZERO; + GLStencilOps[STENCIL_OP_REPLACE] = GL_REPLACE; + GLStencilOps[STENCIL_OP_INCR_SAT] = GL_INCR; + GLStencilOps[STENCIL_OP_DECR_SAT] = GL_DECR; + GLStencilOps[STENCIL_OP_INVERT] = GL_INVERT; + GLStencilOps[STENCIL_OP_INCR_WRAP]= GL_INCR_WRAP; + GLStencilOps[STENCIL_OP_DECR_WRAP]= GL_DECR_WRAP; + bIsInit = true; + } + + if( StencilOp > STENCIL_OP_UNDEFINED && StencilOp < STENCIL_OP_NUM_OPS ) + { + auto GlStencilOp = GLStencilOps[StencilOp]; + VERIFY( GlStencilOp != 0 || GlStencilOp == 0 && StencilOp == STENCIL_OP_ZERO, "Unexpected stencil op" ); + return GlStencilOp; + } + else + { + UNEXPECTED( "Stencil operation (", StencilOp, ") is out of allowed range [1, ", STENCIL_OP_NUM_OPS-1, "]" ); + return 0; + } +} + + +GLenum BlendFactor2GLBlend( BLEND_FACTOR bf ) +{ + static bool bIsInit = false; + static GLenum GLBlend[BLEND_FACTOR_NUM_FACTORS] = {}; + if( !bIsInit ) + { + GLBlend[ BLEND_FACTOR_ZERO ] = GL_ZERO; + GLBlend[ BLEND_FACTOR_ONE ] = GL_ONE; + GLBlend[ BLEND_FACTOR_SRC_COLOR ] = GL_SRC_COLOR; + GLBlend[ BLEND_FACTOR_INV_SRC_COLOR ] = GL_ONE_MINUS_SRC_COLOR; + GLBlend[ BLEND_FACTOR_SRC_ALPHA ] = GL_SRC_ALPHA; + GLBlend[ BLEND_FACTOR_INV_SRC_ALPHA ] = GL_ONE_MINUS_SRC_ALPHA; + GLBlend[ BLEND_FACTOR_DEST_ALPHA ] = GL_DST_ALPHA; + GLBlend[ BLEND_FACTOR_INV_DEST_ALPHA ] = GL_ONE_MINUS_DST_ALPHA; + GLBlend[ BLEND_FACTOR_DEST_COLOR ] = GL_DST_COLOR; + GLBlend[ BLEND_FACTOR_INV_DEST_COLOR ] = GL_ONE_MINUS_DST_COLOR; + GLBlend[ BLEND_FACTOR_SRC_ALPHA_SAT ] = GL_SRC_ALPHA_SATURATE; + GLBlend[ BLEND_FACTOR_BLEND_FACTOR ] = GL_CONSTANT_COLOR; + GLBlend[ BLEND_FACTOR_INV_BLEND_FACTOR ] = GL_ONE_MINUS_CONSTANT_COLOR; + GLBlend[ BLEND_FACTOR_SRC1_COLOR ] = GL_SRC1_COLOR; + GLBlend[ BLEND_FACTOR_INV_SRC1_COLOR ] = GL_ONE_MINUS_SRC1_COLOR; + GLBlend[ BLEND_FACTOR_SRC1_ALPHA ] = GL_SRC1_ALPHA; + GLBlend[ BLEND_FACTOR_INV_SRC1_ALPHA ] = GL_ONE_MINUS_SRC1_ALPHA; + + bIsInit = true; + } + if( bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS ) + { + auto glbf = GLBlend[bf]; + VERIFY( glbf != 0 || glbf == 0 && bf == BLEND_FACTOR_ZERO, "Incorrect blend factor" ); + return glbf; + } + else + { + UNEXPECTED( "Incorrect blend factor (", bf, ")" ); + return 0; + } +} + +GLenum BlendOperation2GLBlendOp( BLEND_OPERATION BlendOp ) +{ + static bool bIsInit = false; + static GLenum GLBlendOp[BLEND_OPERATION_NUM_OPERATIONS] = {}; + if( !bIsInit ) + { + GLBlendOp[ BLEND_OPERATION_ADD ] = GL_FUNC_ADD; + GLBlendOp[ BLEND_OPERATION_SUBTRACT ] = GL_FUNC_SUBTRACT; + GLBlendOp[ BLEND_OPERATION_REV_SUBTRACT ] = GL_FUNC_REVERSE_SUBTRACT; + GLBlendOp[ BLEND_OPERATION_MIN ] = GL_MIN; + GLBlendOp[ BLEND_OPERATION_MAX ] = GL_MAX; + + bIsInit = true; + } + + if( BlendOp > BLEND_OPERATION_UNDEFINED && BlendOp < BLEND_OPERATION_NUM_OPERATIONS ) + { + auto glbop = GLBlendOp[BlendOp]; + VERIFY( glbop != 0, "Incorrect blend operation" ); + return glbop; + } + else + { + UNEXPECTED( "Incorrect blend operation (", BlendOp, ")" ); + return 0; + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GraphicsEngineOpenGL.def b/Graphics/GraphicsEngineOpenGL/src/GraphicsEngineOpenGL.def new file mode 100644 index 00000000..3a128b26 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GraphicsEngineOpenGL.def @@ -0,0 +1,2 @@ +EXPORTS + CreateDeviceAndSwapChainGL
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/src/HLSL2GLSLConverter.cpp b/Graphics/GraphicsEngineOpenGL/src/HLSL2GLSLConverter.cpp new file mode 100644 index 00000000..252383ba --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/HLSL2GLSLConverter.cpp @@ -0,0 +1,3261 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// Converter limitation: +// * Using Texture* keywords in macros is not supported. The following lines will not work: +// - #define TEXTURE2D Texture2D +// TEXTURE2D MacroTex2D; +// +// +// List of supported HLSL Objects and methods: +// +// * Texture1D: +// - void GetDimensions (out {int, uint, float} Width); +// - void GetDimensions (in uint MipLevel, out {int, uint, float} Width, out {int, uint, float} NumberOfLevels); +// - ret Sample( sampler_state S, float Location [, int Offset] ); +// - ret SampleBias( sampler_state S, float Location, float Bias [, int Offset] ); +// - ret SampleLevel( sampler_state S, float Location, float LOD [, int Offset] ) +// - ret SampleGrad( sampler_state S, float Location, float DDX, float DDY [, int Offset] ); +// - float SampleCmp( SamplerComparisonState S, float Location, float CompareValue, [int Offset] ); +// - float SampleCmpLevelZero( SamplerComparisonState S, float Location, float CompareValue, [int Offset] ); +// - ret Load( int Location, [int Offset ] ); +// +// +// * Texture1DArray: +// - void GetDimensions( out {int, uint, float} Width, out {int, uint, float} Elements ); +// - void GetDimensions( in uint MipLevel, out {int, uint, float} Width, out {int, uint, float} Elements, out {int, uint, float} NumberOfLevels ); +// - ret Sample( sampler_state S, float2 Location [, int Offset] ); +// - ret SampleBias( sampler_state S, float2 Location, float Bias [, int Offset] ); +// - ret SampleLevel( sampler_state S, float2 Location, float LOD [, int Offset] ) +// - ret SampleGrad( sampler_state S, float2 Location, float DDX, float DDY [, int Offset] ); +// - float SampleCmp( SamplerComparisonState S, float2 Location, float CompareValue, [int Offset] ); +// - float SampleCmpLevelZero( SamplerComparisonState S, float2 Location, float CompareValue, [int Offset] ); +// - ret Load( int2 Location, [int Offset ] ); +// Remarks: +// - Array index goes in Location.y + +// +// * Texture2D: +// - void GetDimensions( out {int, uint, float} Width, out {int, uint, float} Height ); +// - void GetDimensions( in uint MipLevel, out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} NumberOfLevels ); +// - ret Sample( sampler_state S, float2 Location [, int2 Offset] ); +// - ret SampleBias( sampler_state S, float2 Location, float Bias [, int2 Offset] ); +// - ret SampleLevel( sampler_state S, float2 Location, float LOD [, int2 Offset] ) +// - ret SampleGrad( sampler_state S, float2 Location, float2 DDX, float2 DDY [, int2 Offset] ); +// - float SampleCmp( SamplerComparisonState S, float2 Location, float CompareValue, [int2 Offset] ); +// - float SampleCmpLevelZero( SamplerComparisonState S, float2 Location, float CompareValue [, int2 Offset] ); +// - ret Load( int2 Location, [int2 Offset ] ); +// - ret Gather( sampler_state S, float2 Location [, int2 Offset] ); +// - float4 GatherCmp( SamplerComparisonState S, float2 Location, float CompareValue [, int2 Offset] ); +// +// * Texture2DArray: +// - void GetDimensions( out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Elements ); +// - void GetDimensions( in uint MipLevel, out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Elements, out {int, uint, float} NumberOfLevels ); +// - ret Sample( sampler_state S, float3 Location [, int2 Offset] ); +// - ret SampleBias( sampler_state S, float3 Location, float Bias [, int2 Offset] ); +// - ret SampleLevel( sampler_state S, float3 Location, float LOD [, int2 Offset] ) +// - ret SampleGrad( sampler_state S, float3 Location, float2 DDX, float2 DDY [, int2 Offset] ); +// - float SampleCmp( SamplerComparisonState S, float2 Location, float CompareValue [, int2 Offset] ); +// - ret Load( int Location3 [, int2 Offset ] ); +// - ret Gather( sampler_state S, float3 Location [, int2 Offset] ); +// - float4 GatherCmp( SamplerComparisonState S, float3 Location, float CompareValue [, int2 Offset] ); +// Remarks: +// - Array index goes in Location.z +// - SampleCmpLevelZero() is not supported as there is no corresponding OpenGL instruction. The +// instruction will always return 0. +// +// * Texture3D: +// - void GetDimensions( out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Depth ); +// - void GetDimensions( in uint MipLevel, out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Depth, out {int, uint, float} NumberOfLevels ); +// - ret Sample( sampler_state S, float3 Location [, int3 Offset] ); +// - ret SampleBias( sampler_state S, float3 Location, float Bias [, int3 Offset] ); +// - ret SampleLevel( sampler_state S, float3 Location, float LOD [, int3 Offset] ) +// - ret SampleGrad( sampler_state S, float3 Location, float3 DDX, float3 DDY [, int3 Offset] ); +// - ret Load( int3 Location [, int3 Offset ] ); +// +// * TextureCube: +// - void GetDimensions( out {int, uint, float} Width, out {int, uint, float} Height ); +// - void GetDimensions( in uint MipLevel, out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} NumberOfLevels ); +// - ret Sample( sampler_state S, float3 Location ); +// - ret SampleBias( sampler_state S, float3 Location, float Bias ); +// - ret SampleLevel( sampler_state S, float3 Location, float LOD ) - NO offset version +// - ret SampleGrad( sampler_state S, float3 Location, float3 DDX, float3 DDY ); +// - float SampleCmp( SamplerComparisonState S, float3 Location, float CompareValue ); +// - ret Gather( sampler_state S, float3 Location ); +// - float4 GatherCmp( SamplerComparisonState S, float3 Location, float CompareValue ); +// Remarks: +// - SampleCmpLevelZero() is not supported as there is no corresponding OpenGL instruction. The +// instruction will always return 0. + +// * TextureCubeArray: +// - void GetDimensions( out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Elements ); +// - void GetDimensions( in uint MipLevel, out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Elements, out {int, uint, float} NumberOfLevels ); +// - ret Sample( sampler_state S, float4 Location ); +// - ret SampleBias( sampler_state S, float4 Location, float Bias ); +// - ret SampleLevel( sampler_state S, float4 Location, float LOD ) - NO offset version +// - ret SampleGrad( sampler_state S, float4 Location, float3 DDX, float3 DDY ); +// - float SampleCmp( SamplerComparisonState S, float4 Location, float CompareValue ); +// - ret Gather( sampler_state S, float4 Location ); +// - float4 GatherCmp( SamplerComparisonState S, float4 Location, float CompareValue ); +// Remarks: +// - SampleCmpLevelZero() is not supported as there is no corresponding OpenGL instruction. The +// instruction will always return 0. +// - Array index goes in Location.w +// +// * Texture2DMS: +// - void GetDimensions(out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} NumberOfSamples); +// - ret Load( int2 Location, int Sample, [int2 Offset ] ); +// +// * Texture2DMSArray: +// - void GetDimensions( out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Elements, out {int, uint, float} NumberOfSamples ); +// - ret Load( int3 Location, int Sample, [int2 Offset ] ); +// +// +// * RWTexture1D: +// - void GetDimensions(out {int, uint, float} Width); +// +// * RWTexture1DArray: +// - void GetDimensions(out {int, uint, float} Width, out {int, uint, float} Elements); +// +// * RWTexture2D: +// - void GetDimensions(out {int, uint, float} Width, out {int, uint, float} Height); +// +// * RWTexture2DArray: +// - void GetDimensions(out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Elements); +// +// * RWTexture3D: +// - void GetDimensions(out {int, uint, float} Width, out {int, uint, float} Height, out {int, uint, float} Depth); +// + +// \remarks +// All GetDimensions() functions return valid value in NumberOfLevels only on Desktop GL 4.3+ +// For multisampled textures, GetDimensions() always returns 0 in NumberOfSamples. + + +// Support for HLSL intrinsics: + +// [V] abs( {int, int2, int3, int4, float, float2, float3, float4} ) +// [V] acos( {float, float2, float3, float4} ) +// (-) acos( {matrix types} ) +// [V] all( {bool2, bool3, bool4}) +// (-) all( {bool, int, int2, int3, int4, float, float2, float3, float4, matrix types} ) +// [V] any( {bool2, bool3, bool4}) +// (-) any( {bool, int, int2, int3, int4, float, float2, float3, float4, matrix types} ) +// [V] asdouble( {uint} ) +// [V] asfloat( {int, int2, int3, int4, uint, uint2, uint3, uint4, float, float2, float3, float4} ) +// (-) asfloat( {matrix types} ) +// [V] asint( {int, int2, int3, int4, uint, uint2, uint3, uint4, float, float2, float3, float4} ) +// (-) asint( {matrix types} ) +// [V] asuint( {int, int2, int3, int4, uint, uint2, uint3, uint4, float, float2, float3, float4} ) +// (-) asuint( {matrix types} ) +// [V] asin( {float, float2, float3, float4} ) +// (-) asin( {matrix types} ) +// [V] atan( {float, float2, float3, float4} ) +// (-) atan( {matrix types} ) +// [V] atan2( {float, float2, float3, float4} ) +// (-) atan2( {matrix types} ) +// [V] ceil( {float, float2, float3, float4} ) +// (-) ceil( {matrix types} ) +// [V] clamp( {int, int2, int3, int4, uint, uint2, uint3, uint4, float, float2, float3, float4} ) +// (-) clamp( {matrix types} ) +// [V] cos( {float, float2, float3, float4} ) +// (-) cos( {matrix types} ) +// [V] cosh( {float, float2, float3, float4} ) +// (-) cosh( {matrix types} ) +// [V] countbits( {int, int2, int3, int4, uint, uint2, uint3, uint4} ) +// [V] cross(float3) +// [V] ddx +// [V] ddx_coarse - defined as ddx +// [V] ddx_fine - defined as ddx +// [V] ddy +// [V] ddy_coarse - defined as ddy +// [V] ddy_fine - defined as ddy +// [V] degrees( {float, float2, float3, float4} ) +// (-) degrees( {matrix types} ) +// [V] determinant +// [V] distance( {float, float2, float3, float4} ) +// [V] dot( {float, float2, float3, float4} ) +// (-) dot( {int, int2, int3, int4} ) +// [V] dst - defined as distance +// [V] exp( {float, float2, float3, float4} ) +// (-) exp( {matrix types} ) +// [V] exp2( {float, float2, float3, float4} ) +// (-) exp2( {matrix types} ) +// [V] f16tof32( {int, int2, int3, int4, uint, uint2, uint3, uint4} ) +// [V] f32tof16( {float, float2, float3, float4} ) -> {uint, uint2, uint3, uint4} +// [V] faceforward( {float, float2, float3, float4} ) +// [V] firstbithigh( {int, int2, int3, int4, uint, uint2, uint3, uint4} ) +// [V] firstbitlow( {int, int2, int3, int4, uint, uint2, uint3, uint4} ) +// [V] floor( {float, float2, float3, float4} ) +// (-) floor( {matrix types} ) +// [V] fma( {double, double2, double3, double4} ) +// [V] fmod( {float, float2, float3, float4} ) +// (-) fmod( {matrix types} ) +// [V] frac( {float, float2, float3, float4} ) +// (-) frac( {matrix types} ) +// [V] frexp( {float, float2, float3, float4}, {int, int2, int3, int4} ) +// [V] fwidth( {float, float2, float3, float4} ) +// (-) fwidth( {matrix types} ) +// [V] isfinite( {float, float2, float3, float4} ) - implemented as (!isinf(x) && !isnan(x)) +// [V] isinf( {float, float2, float3, float4} ) +// (-) isinf( {matrix types} ) +// [V] isnan( {float, float2, float3, float4} ) +// (-) isnan( {matrix types} ) +// [V] ldexp( {float, float2, float3, float4}, {int, int2, int3, int4} ) +// [V] length( {float, float2, float3, float4} ) +// [V] lerp( {float, float2, float3, float4} ) +// (-) lerp( {matrix types} ) +// [V] log( {float, float2, float3, float4} ) +// (-) log( {matrix types} ) +// [V] log2( {float, float2, float3, float4} ) +// (-) log2( {matrix types} ) +// [V] log10( {float, float2, float3, float4} ) +// (-) log10( {matrix types} ) +// [V] mad( {float, float2, float3, float4} ) +// (-) mad( {matrix types} ) +// [V] max( {int, int2, int3, int4, uint, uint2, uint3, uint4, float, float2, float3, float4} ) +// (-) max( {matrix types} ) +// [V] min( {int, int2, int3, int4, uint, uint2, uint3, uint4, float, float2, float3, float4} ) +// (-) min( {matrix types} ) +// [V] modf( {float, float2, float3, float4} ) +// (-) modf( {int, int2, int3, int4, matrix types} ) +// [V] mul - defined as a*b +// [V] noise( {float, float2, float3, float4} ) +// [V] normalize( {float, float2, float3, float4} ) +// [V] pow( {float, float2, float3, float4} ) +// (-) pow( {matrix types} ) +// [V] radians( {float, float2, float3, float4} ) +// (-) radians( {matrix types} ) +// [V] rcp( {float, float2, float3, float4} ) - defined as 1.0/(x) +// [V] reflect( {float, float2, float3, float4} ) +// [V] refract( {float, float2, float3, float4} ) +// [V] reversebits( {int, int2, int3, int4, uint, uint2, uint3, uint4} ) +// [V] round( {float, float2, float3, float4} ) +// (-) round( {matrix types} ) +// [V] rsqrt( {float, float2, float3, float4} ) +// (-) rsqrt( {matrix types} ) +// [V] saturate( {float, float2, float3, float4} ) +// [V] sign( {float, float2, float3, float4, int, int2, int3, int4} ) +// (-) sign( {matrix types} ) +// [V] sin( {float, float2, float3, float4} ) +// (-) sin( {matrix types} ) +// [V] sinh( {float, float2, float3, float4} ) +// (-) sinh( {matrix types} ) +// [V] sincos( {float, float2, float3, float4} ) +// [V] smoothstep( {float, float2, float3, float4} ) +// (-) smoothstep( {matrix types} ) +// [V] sqrt( {float, float2, float3, float4} ) +// (-) sqrt( {matrix types} ) +// [V] step( {float, float2, float3, float4} ) +// (-) step( {matrix types} ) +// [V] tan( {float, float2, float3, float4} ) +// (-) tan( {matrix types} ) +// [V] tanh( {float, float2, float3, float4} ) +// (-) tanh( {matrix types} ) +// [V] transpose +// [V] trunc( {float, float2, float3, float4} ) +// (-) trunc( {matrix types} ) + +// [V] AllMemoryBarrier - calls all memory barrier functions in gl +// [V] AllMemoryBarrierWithGroupSync +// [V] DeviceMemoryBarrier - calls image, atomic counter & buffer memory barriers +// [V] DeviceMemoryBarrierWithGroupSync +// [V] GroupMemoryBarrier - calls group memory & shared memory barriers +// [V] GroupMemoryBarrierWithGroupSync + +// [V] InterlockedAdd( {int, uint} ) +// [V] InterlockedAnd( {int, uint} ) +// [V] InterlockedCompareExchange( {int, uint} ) +// [V] InterlockedCompareStore( {int, uint} ) +// [V] InterlockedExchange( {int, uint} ) +// [V] InterlockedMax( {int, uint} ) +// [V] InterlockedMin( {int, uint} ) +// [V] InterlockedOr( {int, uint} ) +// [V] InterlockedXor( {int, uint} ) + +// [ ] Process2DQuadTessFactorsAvg +// [ ] Process2DQuadTessFactorsMax +// [ ] Process2DQuadTessFactorsMin +// [ ] ProcessIsolineTessFactors +// [ ] ProcessQuadTessFactorsAvg +// [ ] ProcessQuadTessFactorsMax +// [ ] ProcessQuadTessFactorsMin +// [ ] ProcessTriTessFactorsAvg +// [ ] ProcessTriTessFactorsMax +// [ ] ProcessTriTessFactorsMin + +// [ ] CheckAccessFullyMapped + +// [ ] GetRenderTargetSampleCount +// [ ] GetRenderTargetSamplePosition + +// [ ] EvaluateAttributeAtCentroid +// [ ] EvaluateAttributeAtSample +// [ ] EvaluateAttributeSnapped + +// [ ] abort +// [ ] errorf +// [ ] printf +// [ ] clip +// [ ] msad4 +// [ ] lit + +// [ ] D3DCOLORtoUBYTE4 + +// Legacy not supported functions: +// [ ] tex1D +// [ ] tex1D +// [ ] tex1Dbias +// [ ] tex1Dgrad +// [ ] tex1Dlod +// [ ] tex1Dproj +// [ ] tex2D +// [ ] tex2D +// [ ] tex2Dbias +// [ ] tex2Dgrad +// [ ] tex2Dlod +// [ ] tex2Dproj +// [ ] tex3D +// [ ] tex3D +// [ ] tex3Dbias +// [ ] tex3Dgrad +// [ ] tex3Dlod +// [ ] tex3Dproj +// [ ] texCUBE +// [ ] texCUBE +// [ ] texCUBEbias +// [ ] texCUBEgrad +// [ ] texCUBElod +// [ ] texCUBEproj + + +#include "pch.h" +#include "HLSL2GLSLConverter.h" +#include "DataBlobImpl.h" +#include <unordered_set> +#include <string> + +namespace Diligent +{ + +inline bool IsNewLine(Char Symbol) +{ + return Symbol == '\r' || Symbol == '\n'; +} + +inline bool IsDelimiter(Char Symbol) +{ + static const Char* Delimeters = " \t\r\n"; + return strchr( Delimeters, Symbol ) != nullptr; +} + +inline bool IsStatementSeparator(Char Symbol) +{ + static const Char* StatementSeparator = ";}"; + return strchr( StatementSeparator, Symbol ) != nullptr; +} + + +// IteratorType may be String::iterator or String::const_iterator. +// While iterator is convertible to const_iterator, +// iterator& cannot be converted to const_iterator& (Microsoft compiler allows +// such conversion, while gcc does not) +template<typename InteratorType> +static bool SkipComment( const String &Input, InteratorType& Pos ) +{ + // // Comment /* Comment + // ^ ^ + if( Pos == Input.end() || *Pos != '/' ) + return false; + + auto NextPos = Pos+1; + // // Comment /* Comment + // ^ ^ + if( NextPos == Input.end() ) + return false; + + if( *NextPos == '/' ) + { + // Skip // comment + Pos = NextPos + 1; + // // Comment + // ^ + for( ; Pos != Input.end() && !IsNewLine(*Pos); ++Pos ); + return true; + } + else if( *NextPos == '*' ) + { + // Skip /* comment */ + Pos = NextPos + 1; + // /* Comment + // ^ + while( Pos != Input.end() ) + { + if( *Pos == '*' ) + { + // /* Comment */ + // ^ + ++Pos; + // /* Comment */ + // ^ + if( Pos == Input.end() ) + break; + if( *Pos == '/' ) + { + ++Pos; + // /* Comment */ + // ^ + break; + } + } + else + { + // Must handle /* **/ properly + ++Pos; + } + } + return true; + } + + return false; +} + +inline bool SkipDelimeters(const String &Input, String::const_iterator &SrcChar) +{ + for( ; SrcChar != Input.end() && IsDelimiter(*SrcChar); ++SrcChar ); + return SrcChar == Input.end(); +} + +// IteratorType may be String::iterator or String::const_iterator. +// While iterator is convertible to const_iterator, +// iterator& cannot be converted to const_iterator& (Microsoft compiler allows +// such conversion, while gcc does not) +template<typename IteratorType> +inline bool SkipDelimetersAndComments(const String &Input, IteratorType &SrcChar) +{ + bool DelimiterFound = false; + bool CommentFound = false; + do + { + DelimiterFound = false; + for( ; SrcChar != Input.end() && IsDelimiter(*SrcChar); ++SrcChar ) + DelimiterFound = true; + + CommentFound = SkipComment(Input, SrcChar); + } while( SrcChar != Input.end() && (DelimiterFound || CommentFound) ); + + return SrcChar == Input.end(); +} + +inline bool SkipIdentifier(const String &Input, String::const_iterator &SrcChar ) +{ + if( SrcChar == Input.end() ) + return true; + + if( isalpha( *SrcChar ) || *SrcChar == '_' ) + { + ++SrcChar; + if( SrcChar == Input.end() ) + return true; + } + else + return false; + + for( ; SrcChar != Input.end() && (isalnum( *SrcChar ) || *SrcChar == '_'); ++SrcChar ); + + return SrcChar == Input.end(); +} + + +HLSL2GLSLConverter::HLSL2GLSLConverter( IShaderSourceInputStreamFactory *pSourceStreamFactory ) : + m_pSourceStreamFactory(pSourceStreamFactory) +{ + // Populate HLSL keywords hash map +#define DEFINE_KEYWORD(kw)m_HLSLKeywords.insert( std::make_pair( #kw, TokenInfo( TokenType::kw, #kw ) ) ) + DEFINE_KEYWORD( cbuffer ); + DEFINE_KEYWORD( Texture1D ); + DEFINE_KEYWORD( Texture1DArray ); + DEFINE_KEYWORD( Texture2D ); + DEFINE_KEYWORD( Texture2DArray ); + DEFINE_KEYWORD( Texture3D ); + DEFINE_KEYWORD( TextureCube ); + DEFINE_KEYWORD( TextureCubeArray ); + DEFINE_KEYWORD( Texture2DMS ); + DEFINE_KEYWORD( Texture2DMSArray ); + DEFINE_KEYWORD( SamplerState ); + DEFINE_KEYWORD( SamplerComparisonState ); + DEFINE_KEYWORD( RWTexture1D ); + DEFINE_KEYWORD( RWTexture1DArray ); + DEFINE_KEYWORD( RWTexture2D ); + DEFINE_KEYWORD( RWTexture2DArray ); + DEFINE_KEYWORD( RWTexture3D ); +#undef DEFINE_KEYWORD + +#define DEFINE_BUILTIN_TYPE(Type)m_HLSLKeywords.insert( std::make_pair( #Type, TokenInfo( TokenType::BuiltInType, #Type ) ) ) + DEFINE_BUILTIN_TYPE( void ); + + DEFINE_BUILTIN_TYPE( float4 ); + DEFINE_BUILTIN_TYPE( float3 ); + DEFINE_BUILTIN_TYPE( float2 ); + DEFINE_BUILTIN_TYPE( float ); + + DEFINE_BUILTIN_TYPE( int4 ); + DEFINE_BUILTIN_TYPE( int3 ); + DEFINE_BUILTIN_TYPE( int2 ); + DEFINE_BUILTIN_TYPE( int ); + + DEFINE_BUILTIN_TYPE( uint4 ); + DEFINE_BUILTIN_TYPE( uint3 ); + DEFINE_BUILTIN_TYPE( uint2 ); + DEFINE_BUILTIN_TYPE( uint ); + + DEFINE_BUILTIN_TYPE( bool4 ); + DEFINE_BUILTIN_TYPE( bool3 ); + DEFINE_BUILTIN_TYPE( bool2 ); + DEFINE_BUILTIN_TYPE( bool ); + + DEFINE_BUILTIN_TYPE( float2x2 ); + DEFINE_BUILTIN_TYPE( float2x3 ); + DEFINE_BUILTIN_TYPE( float2x4 ); + + DEFINE_BUILTIN_TYPE( float3x2 ); + DEFINE_BUILTIN_TYPE( float3x3 ); + DEFINE_BUILTIN_TYPE( float3x4 ); + + DEFINE_BUILTIN_TYPE( float4x2 ); + DEFINE_BUILTIN_TYPE( float4x3 ); + DEFINE_BUILTIN_TYPE( float4x4 ); + DEFINE_BUILTIN_TYPE( matrix ); +#undef DEFINE_BUILTIN_TYPE + + m_HLSLKeywords.insert( std::make_pair( "struct", TokenInfo( TokenType::_struct, "struct" ) ) ); + +#define DEFINE_FLOW_CONTROL_STATEMENT(Statement) m_HLSLKeywords.insert( std::make_pair( #Statement, TokenInfo( TokenType::FlowControl, #Statement ) ) ) + DEFINE_FLOW_CONTROL_STATEMENT( break ); + DEFINE_FLOW_CONTROL_STATEMENT( continue ); + DEFINE_FLOW_CONTROL_STATEMENT( discard ); + DEFINE_FLOW_CONTROL_STATEMENT( do ); + DEFINE_FLOW_CONTROL_STATEMENT( for ); + DEFINE_FLOW_CONTROL_STATEMENT( if ); + DEFINE_FLOW_CONTROL_STATEMENT( else ); + DEFINE_FLOW_CONTROL_STATEMENT( switch ); + DEFINE_FLOW_CONTROL_STATEMENT( while ); + DEFINE_FLOW_CONTROL_STATEMENT( return ); +#undef DEFINE_FLOW_CONTROL_STATEMENT + + + // Prepare texture function stubs + // sampler usampler isampler sampler*Shadow + const String Prefixes[] = { "", "u", "i", "" }; + const String Suffixes[] = { "", "", "", "Shadow" }; + for( int i = 0; i < _countof( Prefixes ); ++i ) + { + const auto &Pref = Prefixes[i]; + const auto &Suff = Suffixes[i]; + // GetDimensions() does not return anything, so swizzle should be empty +#define DEFINE_GET_DIM_STUB(Name, Obj, NumArgs) m_GLSLStubs.emplace( make_pair( FunctionStubHashKey( Pref + Obj + Suff, "GetDimensions", NumArgs ), GLSLStubInfo(Name, "") ) ) + + DEFINE_GET_DIM_STUB( "GetTex1DDimensions_1", "sampler1D", 1 ); // GetDimensions( Width ) + DEFINE_GET_DIM_STUB( "GetTex1DDimensions_3", "sampler1D", 3 ); // GetDimensions( Mip, Width, NumberOfMips ) + + DEFINE_GET_DIM_STUB( "GetTex1DArrDimensions_2", "sampler1DArray", 2 ); // GetDimensions( Width, ArrElems ) + DEFINE_GET_DIM_STUB( "GetTex1DArrDimensions_4", "sampler1DArray", 4 ); // GetDimensions( Mip, Width, ArrElems, NumberOfMips ) + + DEFINE_GET_DIM_STUB( "GetTex2DDimensions_2", "sampler2D", 2 ); // GetDimensions( Width, Height ) + DEFINE_GET_DIM_STUB( "GetTex2DDimensions_4", "sampler2D", 4 ); // GetDimensions( Mip, Width, Height, NumberOfMips ); + + DEFINE_GET_DIM_STUB( "GetTex2DArrDimensions_3", "sampler2DArray", 3 ); // GetDimensions( Width, Height, ArrElems ) + DEFINE_GET_DIM_STUB( "GetTex2DArrDimensions_5", "sampler2DArray", 5 ); // GetDimensions( Mip, Width, Height, ArrElems, NumberOfMips ) + + DEFINE_GET_DIM_STUB( "GetTex2DDimensions_2", "samplerCube", 2 ); // GetDimensions( Width, Height ) + DEFINE_GET_DIM_STUB( "GetTex2DDimensions_4", "samplerCube", 4 ); // GetDimensions( Mip, Width, Height, NumberOfMips ) + + DEFINE_GET_DIM_STUB( "GetTex2DArrDimensions_3", "samplerCubeArray", 3 ); // GetDimensions( Width, Height, ArrElems ) + DEFINE_GET_DIM_STUB( "GetTex2DArrDimensions_5", "samplerCubeArray", 5 ); // GetDimensions( Mip, Width, Height, ArrElems, NumberOfMips ) + + if( Suff == "" ) + { + // No shadow samplers for Tex3D, Tex2DMS and Tex2DMSArr + DEFINE_GET_DIM_STUB( "GetTex3DDimensions_3", "sampler3D", 3 ); // GetDimensions( Width, Height, Depth ) + DEFINE_GET_DIM_STUB( "GetTex3DDimensions_5", "sampler3D", 5 ); // GetDimensions( Mip, Width, Height, Depth, NumberOfMips ) + + DEFINE_GET_DIM_STUB( "GetTex2DMSDimensions_3", "sampler2DMS", 3 ); // GetDimensions( Width, Height, NumSamples ) + DEFINE_GET_DIM_STUB( "GetTex2DMSArrDimensions_4", "sampler2DMSArray", 4 ); // GetDimensions( Width, Height, ArrElems, NumSamples ) + + // Images + DEFINE_GET_DIM_STUB( "GetRWTex1DDimensions_1", "image1D", 1 ); // GetDimensions( Width ) + DEFINE_GET_DIM_STUB( "GetRWTex1DArrDimensions_2", "image1DArray", 2 ); // GetDimensions( Width, ArrElems ) + DEFINE_GET_DIM_STUB( "GetRWTex2DDimensions_2", "image2D", 2 ); // GetDimensions( Width, Height ) + DEFINE_GET_DIM_STUB( "GetRWTex2DArrDimensions_3", "image2DArray", 3 ); // GetDimensions( Width, Height, ArrElems ) + DEFINE_GET_DIM_STUB( "GetRWTex3DDimensions_3", "image3D", 3 ); // GetDimensions( Width, Height, Depth ) + + m_ImageTypes.insert( HashMapStringKey(Pref+"image1D") ); + m_ImageTypes.insert( HashMapStringKey(Pref+"image1DArray") ); + m_ImageTypes.insert( HashMapStringKey(Pref+"image2D") ); + m_ImageTypes.insert( HashMapStringKey(Pref+"image2DArray") ); + m_ImageTypes.insert( HashMapStringKey(Pref+"image3D") ); + } +#undef DEFINE_GET_DIM_STUB + } + + String Dimensions[] = { "1D", "1DArray", "2D", "2DArray", "3D", "Cube", "CubeArray" }; + for( int d = 0; d< _countof( Dimensions ); ++d) + { + String Dim = Dimensions[d]; + for( int i = 0; i < 3; ++i ) + { + auto GLSLSampler = Prefixes[i] + "sampler" + Dim; + + // Use default swizzle to return the same number of components as specified in the texture declaration + // Converter will insert _SWIZZLEn, where n is the number of components, after the function stub. + // Example: + // Texture2D<float3> Tex2D; + // ... + // Tex2D.Sample(Tex2D_sampler, f2UV) -> Sample_2(Tex2D, Tex2D_sampler, f2UV)_SWIZZLE3 + const Char *Swizzle = "_SWIZZLE"; + +#define DEFINE_STUB(Name, Obj, Func, NumArgs) m_GLSLStubs.emplace( make_pair( FunctionStubHashKey( Obj, Func, NumArgs ), GLSLStubInfo(Name, Swizzle) ) ) + + DEFINE_STUB( "Sample_2", GLSLSampler, "Sample", 2 ); // Sample ( Sampler, Location ) + DEFINE_STUB( "SampleBias_3", GLSLSampler, "SampleBias", 3 ); // SampleBias ( Sampler, Location, Bias ) + DEFINE_STUB( "SampleLevel_3", GLSLSampler, "SampleLevel", 3 ); // SampleLevel( Sampler, Location, LOD ) + DEFINE_STUB( "SampleGrad_4", GLSLSampler, "SampleGrad", 4 ); // SampleGrad ( Sampler, Location, DDX, DDY ) + if( Dim != "Cube" && Dim != "CubeArray" ) + { + // No offset versions for cube & cube array + DEFINE_STUB( "Sample_3", GLSLSampler, "Sample", 3 ); // Sample ( Sampler, Location, Offset ) + DEFINE_STUB( "SampleBias_4", GLSLSampler, "SampleBias", 4 ); // SampleBias ( Sampler, Location, Bias, Offset ) + DEFINE_STUB( "SampleLevel_4", GLSLSampler, "SampleLevel", 4 ); // SampleLevel( Sampler, Location, LOD, Offset ) + DEFINE_STUB( "SampleGrad_5", GLSLSampler, "SampleGrad", 5 ); // SampleGrad ( Sampler, Location, DDX, DDY, Offset ) + } + if( Dim != "1D" && Dim != "1DArray" && Dim != "3D" ) + { + // Gather always returns float4 independent of the number of components, so no swizzling + Swizzle = ""; + DEFINE_STUB( "Gather_2", GLSLSampler, "Gather", 2 ); // Gather( SamplerState, Location ) + DEFINE_STUB( "Gather_3", GLSLSampler, "Gather", 3 ); // Gather( SamplerState, Location, Offset ) + } + } + } + + // Gather always returns float4 independent of the number of components, so no swizzling + const Char *Swizzle = ""; + DEFINE_STUB( "GatherCmp_3", "sampler2DShadow", "GatherCmp", 3 ); // GatherCmp( SmplerCmp, Location, CompareValue ) + DEFINE_STUB( "GatherCmp_4", "sampler2DShadow", "GatherCmp", 4 ); // GatherCmp( SmplerCmp, Location, CompareValue, Offset ) + DEFINE_STUB( "GatherCmp_3", "sampler2DArrayShadow", "GatherCmp", 3 ); // GatherCmp( SmplerCmp, Location, CompareValue ) + DEFINE_STUB( "GatherCmp_4", "sampler2DArrayShadow", "GatherCmp", 4 ); // GatherCmp( SmplerCmp, Location, CompareValue, Offset ) + DEFINE_STUB( "GatherCmp_3", "samplerCubeShadow", "GatherCmp", 3 ); // GatherCmp( SmplerCmp, Location, CompareValue ) + DEFINE_STUB( "GatherCmp_3", "samplerCubeArrayShadow", "GatherCmp", 3 ); // GatherCmp( SmplerCmp, Location, CompareValue ) + + // All load operations should return the same number of components as specified + // in texture declaraion, so use swizzling. Example: + // Texture3D<int2> Tex3D; + // ... + // Tex3D.Load(i4Location) -> LoadTex3D_1(Tex3D, i4Location)_SWIZZLE2 + Swizzle = "_SWIZZLE"; + for( int i = 0; i < 3; ++i ) + { + auto Pref = Prefixes[i]; + DEFINE_STUB( "LoadTex1D_1", Pref + "sampler1D", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadTex1DArr_1", Pref + "sampler1DArray", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadTex2D_1", Pref + "sampler2D", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadTex2DArr_1", Pref + "sampler2DArray", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadTex3D_1", Pref + "sampler3D", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadTex2DMS_2", Pref + "sampler2DMS", "Load", 2 ); // Load( Location, Sample ) + DEFINE_STUB( "LoadTex2DMSArr_2", Pref + "sampler2DMSArray", "Load", 2 ); // Load( Location, Sample ) + + DEFINE_STUB( "LoadTex1D_2", Pref + "sampler1D", "Load", 2 ); // Load( Location, Offset ) + DEFINE_STUB( "LoadTex1DArr_2", Pref + "sampler1DArray", "Load", 2 ); // Load( Location, Offset ) + DEFINE_STUB( "LoadTex2D_2", Pref + "sampler2D", "Load", 2 ); // Load( Location, Offset ) + DEFINE_STUB( "LoadTex2DArr_2", Pref + "sampler2DArray", "Load", 2 ); // Load( Location, Offset ) + DEFINE_STUB( "LoadTex3D_2", Pref + "sampler3D", "Load", 2 ); // Load( Location, Offset ) + DEFINE_STUB( "LoadTex2DMS_3", Pref + "sampler2DMS", "Load", 3 ); // Load( Location, Sample, Offset ) + DEFINE_STUB( "LoadTex2DMSArr_3", Pref + "sampler2DMSArray", "Load", 3 ); // Load( Location, Sample, Offset ) + + DEFINE_STUB( "LoadRWTex1D_1", Pref + "image1D", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadRWTex1DArr_1", Pref + "image1DArray", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadRWTex2D_1", Pref + "image2D", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadRWTex2DArr_1", Pref + "image2DArray", "Load", 1 ); // Load( Location ) + DEFINE_STUB( "LoadRWTex3D_1", Pref + "image3D", "Load", 1 ); // Load( Location ) + } + + // SampleCmp() returns float independent of the number of components, so + // use no swizzling + Swizzle = ""; + + DEFINE_STUB( "SampleCmpTex1D_3", "sampler1DShadow", "SampleCmp", 3 ); // SampleCmp( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpTex1DArr_3", "sampler1DArrayShadow", "SampleCmp", 3 ); // SampleCmp( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpTex2D_3", "sampler2DShadow", "SampleCmp", 3 ); // SampleCmp( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpTex2DArr_3", "sampler2DArrayShadow", "SampleCmp", 3 ); // SampleCmp( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpTexCube_3", "samplerCubeShadow", "SampleCmp", 3 ); // SampleCmp( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpTexCubeArr_3", "samplerCubeArrayShadow","SampleCmp", 3 ); // SampleCmp( SamplerCmp, Location, CompareValue ) + + DEFINE_STUB( "SampleCmpTex1D_4", "sampler1DShadow", "SampleCmp", 4 ); // SampleCmp( SamplerCmp, Location, CompareValue, Offset ) + DEFINE_STUB( "SampleCmpTex1DArr_4", "sampler1DArrayShadow", "SampleCmp", 4 ); // SampleCmp( SamplerCmp, Location, CompareValue, Offset ) + DEFINE_STUB( "SampleCmpTex2D_4", "sampler2DShadow", "SampleCmp", 4 ); // SampleCmp( SamplerCmp, Location, CompareValue, Offset ) + DEFINE_STUB( "SampleCmpTex2DArr_4", "sampler2DArrayShadow", "SampleCmp", 4 ); // SampleCmp( SamplerCmp, Location, CompareValue, Offset ) + + + DEFINE_STUB( "SampleCmpLevel0Tex1D_3", "sampler1DShadow", "SampleCmpLevelZero", 3 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpLevel0Tex1DArr_3", "sampler1DArrayShadow", "SampleCmpLevelZero", 3 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpLevel0Tex2D_3", "sampler2DShadow", "SampleCmpLevelZero", 3 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpLevel0Tex2DArr_3", "sampler2DArrayShadow", "SampleCmpLevelZero", 3 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpLevel0TexCube_3", "samplerCubeShadow", "SampleCmpLevelZero", 3 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue ) + DEFINE_STUB( "SampleCmpLevel0TexCubeArr_3", "samplerCubeArrayShadow","SampleCmpLevelZero", 3 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue ) + + DEFINE_STUB( "SampleCmpLevel0Tex1D_4", "sampler1DShadow", "SampleCmpLevelZero", 4 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue, Offset ) + DEFINE_STUB( "SampleCmpLevel0Tex1DArr_4", "sampler1DArrayShadow", "SampleCmpLevelZero", 4 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue, Offset ) + DEFINE_STUB( "SampleCmpLevel0Tex2D_4", "sampler2DShadow", "SampleCmpLevelZero", 4 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue, Offset ) + DEFINE_STUB( "SampleCmpLevel0Tex2DArr_4", "sampler2DArrayShadow", "SampleCmpLevelZero", 4 ); // SampleCmpLevelZero( SamplerCmp, Location, CompareValue, Offset ) + + + // InterlockedOp( dest, val ) + // InterlockedOp( dest, val, original_val ) +#define DEFINE_ATOMIC_OP_STUBS(Op)\ + DEFINE_STUB( "Interlocked" Op "SharedVar_2", "shared_var", "Interlocked" Op, 2 ); \ + DEFINE_STUB( "Interlocked" Op "SharedVar_3", "shared_var", "Interlocked" Op, 3 ); \ + DEFINE_STUB( "Interlocked" Op "Image_2", "image", "Interlocked" Op, 2 ); \ + DEFINE_STUB( "Interlocked" Op "Image_3", "image", "Interlocked" Op, 3 ); \ + m_AtomicOperations.insert( HashMapStringKey("Interlocked" Op) ); + + + DEFINE_ATOMIC_OP_STUBS( "Add" ); + DEFINE_ATOMIC_OP_STUBS( "And" ); + DEFINE_ATOMIC_OP_STUBS( "Exchange" ); + DEFINE_ATOMIC_OP_STUBS( "Max" ); + DEFINE_ATOMIC_OP_STUBS( "Min" ); + DEFINE_ATOMIC_OP_STUBS( "Or" ); + DEFINE_ATOMIC_OP_STUBS( "Xor" ); + + // InterlockedCompareExchange( dest, compare_value, value, original_value ) + DEFINE_STUB( "InterlockedCompareExchangeSharedVar_4", "shared_var", "InterlockedCompareExchange", 4 ); + DEFINE_STUB( "InterlockedCompareExchangeImage_4", "image", "InterlockedCompareExchange", 4 ); + m_AtomicOperations.insert( HashMapStringKey("InterlockedCompareExchange") ); + + // InterlockedCompareStore( dest, compare_value, value ) + DEFINE_STUB( "InterlockedCompareStoreSharedVar_3", "shared_var", "InterlockedCompareStore", 3 ); + DEFINE_STUB( "InterlockedCompareStoreImage_3", "image", "InterlockedCompareStore", 3 ); + m_AtomicOperations.insert( HashMapStringKey("InterlockedCompareStore") ); + +#undef DEFINE_STUB +} + +String CompressNewLines( const String& Str ) +{ + String Out; + auto Char = Str.begin(); + while( Char != Str.end() ) + { + if( *Char == '\r' ) + { + ++Char; + // Replace \r\n with \n + if( Char != Str.end() && *Char == '\n' ) + { + Out.push_back( '\n' ); + ++Char; + } + else + Out.push_back( '\r' ); + } + else + { + Out.push_back( *(Char++) ); + } + } + return Out; +} + +static Int32 CountNewLines(const String& Str) +{ + Int32 NumNewLines = 0; + auto Char = Str.begin(); + while( Char != Str.end() ) + { + if( *Char == '\r' ) + { + ++NumNewLines; + ++Char; + // \r\n should be counted as one newline + if( Char != Str.end() && *Char == '\n' ) + ++Char; + } + else + { + if( *Char == '\n' ) + ++NumNewLines; + ++Char; + } + } + return NumNewLines; +} + + +// IteratorType may be String::iterator or String::const_iterator. +// While iterator is convertible to const_iterator, +// iterator& cannot be converted to const_iterator& (Microsoft compiler allows +// such conversion, while gcc does not) +template<typename IteratorType> +String HLSL2GLSLConverter::PrintTokenContext( IteratorType &TargetToken, Int32 NumAdjacentLines ) +{ + if( TargetToken == m_Tokens.end() ) + --TargetToken; + + //\n ++ x ; + //\n ++ y ; + //\n if ( x != 0 ) + // ^ + //\n x += y ; + //\n + //\n if ( y != 0 ) + //\n x += 2 ; + + const int NumSepChars = 20; + String Ctx(">"); + for( int i = 0; i < NumSepChars; ++i )Ctx.append( " >" ); + Ctx.push_back( '\n' ); + + // Find first token in the current line + auto CurrLineStartToken = TargetToken; + Int32 NumLinesAbove = 0; + while( CurrLineStartToken != m_Tokens.begin() ) + { + NumLinesAbove += CountNewLines(CurrLineStartToken->Delimiter); + if( NumLinesAbove > 0 ) + break; + --CurrLineStartToken; + } + //\n if( x != 0 ) + // ^ + + // Find first token in the line NumAdjacentLines above + auto TopLineStart = CurrLineStartToken; + while( TopLineStart != m_Tokens.begin() && NumLinesAbove <= NumAdjacentLines ) + { + --TopLineStart; + NumLinesAbove += CountNewLines(TopLineStart->Delimiter); + } + //\n ++ x ; + // ^ + //\n ++ y ; + //\n if ( x != 0 ) + + // Write everything from the top line up to the current line start + auto Token = TopLineStart; + for( ; Token != CurrLineStartToken; ++Token ) + { + Ctx.append( CompressNewLines(Token->Delimiter) ); + Ctx.append(Token->Literal); + } + + //\n if ( x != 0 ) + // ^ + + Int32 NumLinesBelow = 0; + String Spaces; // Accumulate whitespaces preceding current token + bool AccumWhiteSpaces = true; + while( Token != m_Tokens.end() && NumLinesBelow == 0 ) + { + if( AccumWhiteSpaces ) + { + for( const auto &Char : Token->Delimiter ) + { + if( IsNewLine( Char ) ) + Spaces.clear(); + else if( Char == '\t' ) + Spaces.push_back( Char ); + else + Spaces.push_back( ' ' ); + } + } + + // Acumulate spaces until we encounter current token + if( Token == TargetToken ) + AccumWhiteSpaces = false; + + if( AccumWhiteSpaces ) + Spaces.append( Token->Literal.length(), ' ' ); + + Ctx.append( CompressNewLines(Token->Delimiter) ); + Ctx.append(Token->Literal); + ++Token; + + if( Token == m_Tokens.end() ) + break; + + NumLinesBelow += CountNewLines(Token->Delimiter); + } + + // Write ^ on the line below + Ctx.push_back( '\n' ); + Ctx.append( Spaces ); + Ctx.push_back( '^' ); + + // Write NumAdjacentLines lines below current line + while( Token != m_Tokens.end() && NumLinesBelow <= NumAdjacentLines ) + { + Ctx.append( CompressNewLines(Token->Delimiter) ); + Ctx.append(Token->Literal); + ++Token; + + if( Token == m_Tokens.end() ) + break; + + NumLinesBelow += CountNewLines(Token->Delimiter); + } + + Ctx.append("\n<"); + for( int i = 0; i < NumSepChars; ++i )Ctx.append( " <" ); + Ctx.push_back( '\n' ); + + return Ctx; +} + + +#define VERIFY_PARSER_STATE( Token, Condition, ... )\ + if( !(Condition) ) \ + { \ + Diligent::MsgStream ss; \ + Diligent::FormatMsg( ss, __VA_ARGS__ ); \ + LOG_ERROR_AND_THROW( ss.str(), "\n", PrintTokenContext(Token, 4) );\ + } + +template<typename IterType> +bool SkipPrefix(const Char* RefStr, IterType &begin, IterType end) +{ + auto pos = begin; + while( *RefStr && pos != end ) + { + if( *(RefStr++) != *(pos++) ) + return false; + } + if( *RefStr == 0 ) + { + begin = pos; + return true; + } + + return false; +} + +// The method scans the source code and replaces +// all #include directives with the contents of the +// file. It maintains a set of already parsed includes +// to avoid double inclusion +void HLSL2GLSLConverter::InsertIncludes( String &GLSLSource ) +{ + // Put all the includes into the set to avoid multiple inclusion + std::unordered_set<String> ProcessedIncludes; + + do + { + // Find the first #include statement + auto Pos = GLSLSource.begin(); + auto IncludeStartPos = GLSLSource.end(); + while( Pos != GLSLSource.end() ) + { + // # include "TestFile.fxh" + if( SkipDelimetersAndComments( GLSLSource, Pos ) ) + break; + if( *Pos == '#' ) + { + IncludeStartPos = Pos; + // # include "TestFile.fxh" + // ^ + ++Pos; + // # include "TestFile.fxh" + // ^ + if( SkipDelimetersAndComments( GLSLSource, Pos ) ) + { + // End of the file reached - break + break; + } + // # include "TestFile.fxh" + // ^ + if( SkipPrefix( "include", Pos, GLSLSource.end() ) ) + { + // # include "TestFile.fxh" + // ^ + break; + } + else + { + // This is not an #include directive: + // #define MACRO + // Continue search through the file + } + } + else + ++Pos; + } + + // No more #include found + if( Pos == GLSLSource.end() ) + break; + + // Find open quotes + if( SkipDelimetersAndComments( GLSLSource, Pos ) ) + LOG_ERROR_AND_THROW( "Unexpected EOF after #include directive" ); + // # include "TestFile.fxh" + // ^ + if( *Pos != '\"' && *Pos != '<' ) + LOG_ERROR_AND_THROW( "Missing open quotes or \'<\' after #include directive" ); + ++Pos; + // # include "TestFile.fxh" + // ^ + auto IncludeNameStartPos = Pos; + // Find closing quotes + while( Pos != GLSLSource.end() && *Pos != '\"' && *Pos != '>' )++Pos; + // # include "TestFile.fxh" + // ^ + if( Pos == GLSLSource.end() ) + LOG_ERROR_AND_THROW( "Missing closing quotes or \'>\' after #include directive" ); + + // Get the name of the include file + auto IncludeName = String( IncludeNameStartPos, Pos ); + ++Pos; + // # include "TestFile.fxh" + // ^ ^ + // IncludeStartPos Pos + GLSLSource.erase( IncludeStartPos, Pos ); + + // Convert the name to lower case + String IncludeFileLowercase = IncludeName; + std::transform( IncludeFileLowercase.begin(), IncludeFileLowercase.end(), IncludeFileLowercase.begin(), ::tolower ); + // Insert the lower-case name into the set + auto It = ProcessedIncludes.insert( IncludeFileLowercase ); + // If the name was actually inserted, which means the include encountered for the first time, + // replace the text with the file content + if( It.second ) + { + RefCntAutoPtr<IFileStream> pIncludeDataStream; + m_pSourceStreamFactory->CreateInputStream( IncludeName.c_str(), &pIncludeDataStream ); + if( !pIncludeDataStream ) + LOG_ERROR_AND_THROW( "Failed to open include file ", IncludeName ) + RefCntAutoPtr<Diligent::IDataBlob> pIncludeData( new Diligent::DataBlobImpl ); + pIncludeDataStream->Read( pIncludeData ); + + // Get include text + auto IncludeText = reinterpret_cast<const Char*> (pIncludeData->GetDataPtr()); + size_t NumSymbols = pIncludeData->GetSize(); + + // Insert the text into source + GLSLSource.insert( IncludeStartPos-GLSLSource.begin(), IncludeText, NumSymbols ); + } + } while( true ); +} + + +void ReadNumericConstant(const String &Source, String::const_iterator &Pos, String &Output) +{ +#define COPY_SYMBOL(){ Output.push_back( *(Pos++) ); if( Pos == Source.end() )return; } + + while( Pos != Source.end() && *Pos >= '0' && *Pos <= '9' ) + COPY_SYMBOL() + + if( *Pos == '.' ) + { + COPY_SYMBOL() + // Copy all numbers + while( Pos != Source.end() && *Pos >= '0' && *Pos <= '9' ) + COPY_SYMBOL() + } + + // Scientific notation + // e+1242, E-234 + if( *Pos == 'e' || *Pos == 'E' ) + { + COPY_SYMBOL() + + if( *Pos == '+' || *Pos == '-' ) + COPY_SYMBOL() + + // Skip all numbers + while( Pos != Source.end() && *Pos >= '0' && *Pos <= '9' ) + COPY_SYMBOL() + } + + if( *Pos == 'f' || *Pos == 'F' ) + COPY_SYMBOL() +#undef COPY_SYMBOL +} + + +// The function convertes source code into a token list +void HLSL2GLSLConverter::Tokenize( const String &Source ) +{ +#define CHECK_END(...) \ + if( SrcPos == Source.end() ) \ + { \ + LOG_ERROR_MESSAGE(__VA_ARGS__) \ + break; \ + } + + int OpenBracketCount = 0; + int OpenBraceCount = 0; + int OpenStapleCount = 0; + + // Push empty node in the beginning of the list to facilitate + // backwards searching + m_Tokens.push_back( TokenInfo() ); + + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509638(v=vs.85).aspx + + // Notes: + // * Operators +, - are not detected + // * This might be a + b, -a or -10 + // * Operator ?: is not detected + auto SrcPos = Source.begin(); + while( SrcPos != Source.end() ) + { + TokenInfo NewToken; + auto DelimStart = SrcPos; + SkipDelimetersAndComments( Source, SrcPos ); + if( DelimStart != SrcPos ) + { + auto DelimSize = SrcPos - DelimStart; + NewToken.Delimiter.reserve(DelimSize); + NewToken.Delimiter.append(DelimStart, SrcPos); + } + if( SrcPos == Source.end() ) + break; + + switch( *SrcPos ) + { + case '#': + { + NewToken.Type = TokenType::PreprocessorDirective; + auto DirectiveStart = SrcPos; + ++SrcPos; + SkipDelimetersAndComments( Source, SrcPos ); + CHECK_END( "Missing preprocessor directive" ); + SkipIdentifier( Source, SrcPos ); + auto DirectiveSize = SrcPos - DirectiveStart; + NewToken.Literal.reserve(DirectiveSize); + NewToken.Literal.append(DirectiveStart, SrcPos); + } + break; + + case ';': + NewToken.Type = TokenType::Semicolon; + NewToken.Literal.push_back( *(SrcPos++) ); + break; + + case '=': + if( m_Tokens.size() > 0 && NewToken.Delimiter == "" ) + { + auto &LastToken = m_Tokens.back(); + // +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^= + if( LastToken.Literal == "+" || + LastToken.Literal == "-" || + LastToken.Literal == "*" || + LastToken.Literal == "/" || + LastToken.Literal == "%" || + LastToken.Literal == "<<" || + LastToken.Literal == ">>" || + LastToken.Literal == "&" || + LastToken.Literal == "|" || + LastToken.Literal == "^") + { + LastToken.Type = TokenType::Assignment; + LastToken.Literal.push_back( *(SrcPos++) ); + continue; + } + else if( LastToken.Literal == "<" || + LastToken.Literal == ">" || + LastToken.Literal == "=" || + LastToken.Literal == "!" ) + { + LastToken.Type = TokenType::ComparisonOp; + LastToken.Literal.push_back( *(SrcPos++) ); + continue; + } + } + + NewToken.Type = TokenType::Assignment; + NewToken.Literal.push_back( *(SrcPos++) ); + break; + + case '|': + case '&': + if( m_Tokens.size() > 0 && NewToken.Delimiter == "" && + m_Tokens.back().Literal.length() == 1 && m_Tokens.back().Literal[0] == *SrcPos ) + { + m_Tokens.back().Type = TokenType::BooleanOp; + m_Tokens.back().Literal.push_back( *(SrcPos++) ); + continue; + } + else + { + NewToken.Type = TokenType::BitwiseOp; + NewToken.Literal.push_back( *(SrcPos++) ); + } + break; + + case '<': + case '>': + if( m_Tokens.size() > 0 && NewToken.Delimiter == "" && + m_Tokens.back().Literal.length() == 1 && m_Tokens.back().Literal[0] == *SrcPos ) + { + m_Tokens.back().Type = TokenType::BitwiseOp; + m_Tokens.back().Literal.push_back( *(SrcPos++) ); + continue; + } + else + { + // Note: we do not distinguish between comparison operators + // and template arguments like in Texture2D<float> at this + // point. This will be clarified when textures are processed. + NewToken.Type = TokenType::ComparisonOp; + NewToken.Literal.push_back( *(SrcPos++) ); + } + break; + + case '+': + case '-': + if( m_Tokens.size() > 0 && NewToken.Delimiter == "" && + m_Tokens.back().Literal.length() == 1 && m_Tokens.back().Literal[0] == *SrcPos ) + { + m_Tokens.back().Type = TokenType::IncDecOp; + m_Tokens.back().Literal.push_back( *(SrcPos++) ); + continue; + } + else + { + // We do not currently distinguish between math operator a + b, + // unary operator -a and numerical constant -1: + NewToken.Literal.push_back( *(SrcPos++) ); + } + break; + + case '~': + case '^': + NewToken.Type = TokenType::BitwiseOp; + NewToken.Literal.push_back( *(SrcPos++) ); + break; + + case '*': + case '/': + case '%': + NewToken.Type = TokenType::MathOp; + NewToken.Literal.push_back( *(SrcPos++) ); + break; + + case '!': + NewToken.Type = TokenType::BooleanOp; + NewToken.Literal.push_back( *(SrcPos++) ); + break; + + case ',': + NewToken.Type = TokenType::Comma; + NewToken.Literal.push_back( *(SrcPos++) ); + break; + +#define BRACKET_CASE(Symbol, TokenType, Action) \ + case Symbol: \ + NewToken.Type = TokenType; \ + NewToken.Literal.push_back( *(SrcPos++) ); \ + Action; \ + break; + BRACKET_CASE( '(', TokenType::OpenBracket, ++OpenBracketCount ); + BRACKET_CASE( ')', TokenType::ClosingBracket, --OpenBracketCount ); + BRACKET_CASE( '{', TokenType::OpenBrace, ++OpenBraceCount ); + BRACKET_CASE( '}', TokenType::ClosingBrace, --OpenBraceCount ); + BRACKET_CASE( '[', TokenType::OpenStaple, ++OpenStapleCount ); + BRACKET_CASE( ']', TokenType::ClosingStaple, --OpenStapleCount ); +#undef BRACKET_CASE + + + default: + { + auto IdentifierStartPos = SrcPos; + SkipIdentifier( Source, SrcPos ); + if( IdentifierStartPos != SrcPos ) + { + auto IDSize = SrcPos - IdentifierStartPos; + NewToken.Literal.reserve( IDSize ); + NewToken.Literal.append( IdentifierStartPos, SrcPos ); + auto KeywordIt = m_HLSLKeywords.find(NewToken.Literal.c_str()); + if( KeywordIt != m_HLSLKeywords.end() ) + { + NewToken.Type = KeywordIt->second.Type; + VERIFY( NewToken.Literal == KeywordIt->second.Literal, "Inconsistent literal" ); + } + else + { + NewToken.Type = TokenType::Identifier; + } + } + + if( NewToken.Type == TokenType::Undefined ) + { + bool bIsNumericalCostant = *SrcPos >= '0' && *SrcPos <= '9'; + if( !bIsNumericalCostant && *SrcPos == '.' ) + { + auto NextPos = SrcPos+1; + bIsNumericalCostant = NextPos != Source.end() && *NextPos >= '0' && *NextPos <= '9'; + } + if( bIsNumericalCostant ) + { + ReadNumericConstant(Source, SrcPos, NewToken.Literal); + NewToken.Type = TokenType::NumericConstant; + } + } + + if( NewToken.Type == TokenType::Undefined ) + { + NewToken.Literal.push_back( *(SrcPos++) ); + } + // Operators + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx + } + + } + + m_Tokens.push_back( NewToken ); + } +#undef CHECK_END +} + +void HLSL2GLSLConverter::FindClosingBracket( TokenListType::iterator &Token, + const TokenListType::iterator &ScopeEnd, + TokenType OpenBracketType, + TokenType ClosingBracketType ) +{ + VERIFY_EXPR( Token->Type == OpenBracketType ); + ++Token; // Skip open bracket + int BracketCount = 1; + // Find matching closing bracket + while( Token != ScopeEnd ) + { + if( Token->Type == OpenBracketType ) + ++BracketCount; + else if( Token->Type == ClosingBracketType ) + { + --BracketCount; + if( BracketCount == 0 ) + break; + } + ++Token; + } + VERIFY_PARSER_STATE( Token, BracketCount == 0, "No matching closing bracket found in the scope" ); +} + +// The function replaces cbuffer with uniform and adds semicolon if it is missing after the closing brace: +// cbuffer +// { +// ... +// }; <- Semicolon must be here +// +void HLSL2GLSLConverter::ProcessConstantBuffer( TokenListType::iterator &Token ) +{ + VERIFY_EXPR( Token->Type == TokenType::cbuffer ); + + // Replace "cbuffer" with "uniform" + Token->Literal = "uniform"; + ++Token; + // cbuffer CBufferName + // ^ + + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected EOF after \"cbuffer\" keyword" ); + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::Identifier, "Identifier expected after \"cbuffer\" keyword" ); + const auto& CBufferName = Token->Literal; + + ++Token; + // cbuffer CBufferName + // ^ + while( Token != m_Tokens.end() && Token->Type != TokenType::OpenBrace ) + ++Token; + // cbuffer CBufferName + // { + // ^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Missing open brace in the definition of cbuffer ", CBufferName ); + + // Find closing brace + FindClosingBracket( Token, m_Tokens.end(), TokenType::OpenBrace, TokenType::ClosingBrace ); + + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "No matching closing brace found in the definition of cbuffer ", CBufferName ); + ++Token; // Skip closing brace + // cbuffer CBufferName + // { + // ... + // } + // int a + // ^ + + if( Token == m_Tokens.end() || Token->Type != TokenType::Semicolon ) + { + m_Tokens.insert( Token, TokenInfo( TokenType::Semicolon, ";" ) ); + // cbuffer CBufferName + // { + // ... + // }; + // int a; + // ^ + } +} + + +// The function finds all sampler states in the current scope ONLY, and puts them into the +// hash table. The hash table indicates if the sampler is comparison or not. It is required to +// match HLSL texture declaration to sampler* or sampler*Shadow. +// +// GLSL only allows samplers as uniform variables and function agruments. It does not allow +// local variables of sampler type. So the two possible scopes the function can process are +// global scope and the function argument list. +// +// Only samplers in the current scope are processed, all samplers in nested scopes are ignored +// +// After the function returns, Token points to the end of the scope (m_Tokens.end() for global scope, +// or closing bracket for the function argument list) +// +// Example 1: +// +// Token +// | +// SamplerState g_Sampler; +// SamplerComparsionState g_CmpSampler; +// void Function(in SamplerState in_Sampler) +// { +// } +// +// SamplersHash = { {g_Sampler, "false"}, { {g_CmpSampler, "true"} } +// +// Example 2: +// +// SamplerState g_Sampler; +// SamplerComparsionState g_CmpSampler; +// Token +// | +// void Function(in SamplerState in_Sampler) +// { +// } +// +// SamplersHash = { {in_Sampler, "false"} } +// +void HLSL2GLSLConverter::ParseSamplers( TokenListType::iterator &Token, SamplerHashType &SamplersHash ) +{ + VERIFY_EXPR( Token->Type == TokenType::OpenBracket || Token->Type == TokenType::OpenBrace || Token == m_Tokens.begin() ); + Uint32 ScopeDepth = 1; + bool IsFunctionArgumentList = Token->Type == TokenType::OpenBracket; + + // Skip scope start symbol, which is either open bracket or m_Tokens.begin() + ++Token; + while( Token != m_Tokens.end() && ScopeDepth > 0 ) + { + if( Token->Type == TokenType::OpenBracket || + Token->Type == TokenType::OpenBrace ) + { + // Increase scope depth + ++ScopeDepth; + ++Token; + } + else if(Token->Type == TokenType::ClosingBracket || + Token->Type == TokenType::ClosingBrace ) + { + // Decrease scope depth + --ScopeDepth; + if( ScopeDepth == 0 ) + break; + ++Token; + } + else if( ( Token->Type == TokenType::SamplerState || + Token->Type == TokenType::SamplerComparisonState ) && + // ONLY parse sampler states in the current scope, skip + // all nested scopes + ScopeDepth == 1 ) + { + const auto &SamplerType = Token->Literal; + bool bIsComparison = Token->Type == TokenType::SamplerComparisonState; + // SamplerState LinearClamp; + // ^ + ++Token; + + // There may be a number of samplers declared after single + // Sampler[Comparison]State keyword: + // SamplerState Tex2D1_sampler, Tex2D2_sampler; + do + { + // SamplerState LinearClamp; + // ^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected EOF in ", SamplerType, " declaration" ); + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::Identifier, "Missing identifier in ", SamplerType, " declaration" ); + const auto &SamplerName = Token->Literal; + + // Add sampler state into the hash map + SamplersHash.insert( std::make_pair( SamplerName, bIsComparison ) ); + + ++Token; + // SamplerState LinearClamp ; + // ^ + + // We cannot just remove sampler declarations, because samplers can + // be passed to functions as arguments. + // SamplerState and SamplerComparisonState are #defined as int, so all + // sampler variables will just be unused global variables or function parameters. + // Hopefully GLSL compiler will be able to optimize them out. + + if( IsFunctionArgumentList ) + { + // In function argument list, every arument + // has its own type declaration + break; + } + + // Go to the next sampler declaraion or statement end + while( Token != m_Tokens.end() && Token->Type != TokenType::Comma && Token->Type != TokenType::Semicolon ) + ++Token; + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected EOF while parsing ", SamplerType, " declaration" ); + + if( Token->Type == TokenType::Comma ) + { + // SamplerState Tex2D1_sampler, Tex2D2_sampler ; + // ^ + ++Token; + // SamplerState Tex2D1_sampler, Tex2D2_sampler ; + // ^ + } + else + { + // SamplerState Tex2D1_sampler, Tex2D2_sampler ; + // ^ + break; + } + }while( Token != m_Tokens.end() ); + } + else + ++Token; + } + VERIFY_PARSER_STATE( Token, ScopeDepth == 1 && Token == m_Tokens.end() || ScopeDepth == 0, "Error parsing scope" ); +} + +void ParseImageFormat(const String &Comment, String& ImageFormat) +{ + // /* format = r32f */ + // ^ + auto Pos = Comment.begin(); + if( SkipDelimeters( Comment, Pos ) ) + return; + // /* format = r32f */ + // ^ + if( *Pos != '/' ) + return; + ++Pos; + // /* format = r32f */ + // ^ + // // format = r32f + // ^ + if( Pos == Comment.end() || (*Pos != '/' && *Pos != '*') ) + return; + ++Pos; + // /* format = r32f */ + // ^ + if( SkipDelimeters( Comment, Pos ) ) + return; + // /* format = r32f */ + // ^ + if( !SkipPrefix( "format", Pos, Comment.end() ) ) + return; + // /* format = r32f */ + // ^ + if( SkipDelimeters( Comment, Pos ) ) + return; + // /* format = r32f */ + // ^ + if( *Pos != '=' ) + return; + ++Pos; + // /* format = r32f */ + // ^ + if( SkipDelimeters( Comment, Pos ) ) + return; + // /* format = r32f */ + // ^ + + auto ImgFmtStartPos = Pos; + SkipIdentifier( Comment, Pos ); + + ImageFormat = String( ImgFmtStartPos, Pos ); +} + +// The function processes texture declaration that is indicated by Token, converts it to +// corresponding GLSL sampler type and adds the new sampler into Objects hash map. +// +// Samplers is the stack of sampler states found in all nested scopes. +// GLSL only supports samplers as global uniform variables or function arguments. +// Consequently, there are two possible levels in Samplers stack: +// level 0 - global sampler states (always present) +// level 1 - samplers declared as function arguments (only present when parsing function body) +// +// The function uses the following rules to convert HLSL texture declaration into GLSL sampler: +// - HLSL texture dimension defines GLSL sampler dimension: +// - Texture2D -> sampler2D +// - TextureCube -> samplerCube +// - HLSL texture component type defines GLSL sampler type. If no type is specified, float4 is assumed: +// - Texture2D<float> -> sampler2D +// - Texture3D<uint4> -> usampler3D +// - Texture2DArray<int2> -> isampler2DArray +// - Texture2D -> sampler2D +// - To distinguish if sampler should be shadow or not, the function tries to find <Texture Name>_sampler +// in the provided sampler state stack. If the sampler type is comparison, the texture is converted +// to shadow sampler. If sampler state is either not comparison or not found, regular sampler is used +// Examples: +// - Texture2D g_ShadowMap; -> sampler2DShadow +// SamplerComparisonState g_ShadowMap_sampler; +// - Texture2D g_Tex2D; -> sampler2D g_Tex2D; +// SamplerState g_Tex2D_sampler; +// Texture3D g_Tex3D; -> sampler3D g_Tex3D; +// +void HLSL2GLSLConverter::ProcessTextureDeclaration( TokenListType::iterator &Token, + const std::vector<SamplerHashType> &Samplers, + ObjectsTypeHashType &Objects ) +{ + auto TexDeclToken = Token; + auto TextureType = TexDeclToken->Type; + // Texture2D < float > ... ; + // ^ + bool IsRWTexture = + TextureType == TokenType::RWTexture1D || + TextureType == TokenType::RWTexture1DArray || + TextureType == TokenType::RWTexture2D || + TextureType == TokenType::RWTexture2DArray || + TextureType == TokenType::RWTexture3D; + + ++Token; + // Texture2D < float > ... ; + // ^ +#define CHECK_EOF() VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected EOF in ", TexDeclToken->Literal, " declaration" ) + CHECK_EOF(); + + auto TypeDefinitionStart = Token; + String GLSLSampler; + String LayoutQualifier; + Uint32 NumComponents = 0; + if( Token->Literal == "<" ) + { + // Fix token type + VERIFY_EXPR( Token->Type == TokenType::ComparisonOp ); + Token->Type = TokenType::OpenAngleBracket; + + ++Token; + CHECK_EOF(); + // Texture2D < float > ... ; + // ^ + auto TexFmtToken = Token; + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::BuiltInType, "Texture format type must be built-in type" ); + if( Token->Literal == "float" || Token->Literal == "float2" || + Token->Literal == "float3" || Token->Literal == "float4" ) + { + if( Token->Literal == "float" ) + NumComponents = 1; + else + NumComponents = Token->Literal.back() - '0'; + } + else if( Token->Literal == "int" || Token->Literal == "int2" || + Token->Literal == "int3" || Token->Literal == "int4" ) + { + GLSLSampler.push_back( 'i' ); + if( Token->Literal == "int" ) + NumComponents = 1; + else + NumComponents = Token->Literal.back() - '0'; + } + else if( Token->Literal == "uint" || Token->Literal == "uint2" || + Token->Literal == "uint3" || Token->Literal == "uint4" ) + { + GLSLSampler.push_back( 'u' ); + if( Token->Literal == "uint" ) + NumComponents = 1; + else + NumComponents = Token->Literal.back() - '0'; + } + else + { + VERIFY_PARSER_STATE( Token, false, Token->Literal, " is not valid texture component type\n" + "Only the following texture element types are supported: float[2,3,4], int[2,3,4], uint[2,3,4]"); + } + VERIFY_PARSER_STATE( Token, NumComponents >= 1 && NumComponents <= 4, "Between 1 and 4 components expected, ", NumComponents ," deduced"); + + ++Token; + CHECK_EOF(); + // Texture2D < float > ... ; + // ^ + if( (TextureType == TokenType::Texture2DMS || + TextureType == TokenType::Texture2DMSArray ) && + Token->Literal == "," ) + { + // Texture2DMS < float, 4 > ... ; + // ^ + ++Token; + CHECK_EOF(); + // Texture2DMS < float, 4 > ... ; + // ^ + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::NumericConstant, "Number of samples is expected in ", TexDeclToken->Literal, " declaration" ); + + // We do not really need the number of samples, so just skip it + ++Token; + CHECK_EOF(); + // Texture2DMS < float, 4 > ... ; + // ^ + } + VERIFY_PARSER_STATE( Token, Token->Literal == ">", "Missing \">\" in ", TexDeclToken->Literal, " declaration" ); + // Fix token type + VERIFY_EXPR( Token->Type == TokenType::ComparisonOp ); + Token->Type = TokenType::ClosingAngleBracket; + + if( IsRWTexture ) + { + String ImgFormat; + // RWTexture2D<float /* format = r32f */ > + // ^ + ParseImageFormat( Token->Delimiter, ImgFormat ); + if( ImgFormat.length() == 0 ) + { + // RWTexture2D</* format = r32f */ float > + // ^ + // TexFmtToken + ParseImageFormat( TexFmtToken->Delimiter, ImgFormat ); + } + + if( ImgFormat.length() != 0 ) + { + LayoutQualifier = String("layout(") + ImgFormat + ") "; + } + } + + ++Token; + // Texture2D < float > TexName ; + // ^ + CHECK_EOF(); + } + + if( IsRWTexture ) + GLSLSampler.append( "image" ); + else + GLSLSampler.append( "sampler" ); + + switch( TextureType ) + { + case TokenType::RWTexture1D: + case TokenType::Texture1D: GLSLSampler += "1D"; break; + + case TokenType::RWTexture1DArray: + case TokenType::Texture1DArray: GLSLSampler += "1DArray"; break; + + case TokenType::RWTexture2D: + case TokenType::Texture2D: GLSLSampler += "2D"; break; + + case TokenType::RWTexture2DArray: + case TokenType::Texture2DArray: GLSLSampler += "2DArray"; break; + + case TokenType::RWTexture3D: + case TokenType::Texture3D: GLSLSampler += "3D"; break; + + case TokenType::TextureCube: GLSLSampler += "Cube"; break; + case TokenType::TextureCubeArray: GLSLSampler += "CubeArray"; break; + case TokenType::Texture2DMS: GLSLSampler += "2DMS"; break; + case TokenType::Texture2DMSArray: GLSLSampler += "2DMSArray"; break; + default: UNEXPECTED("Unexpected texture type"); + } + + // TypeDefinitionStart + // | + // Texture2D < float > TexName ; + // ^ + m_Tokens.erase( TypeDefinitionStart, Token ); + // Texture2D TexName ; + // ^ + + bool IsGlobalScope = Samplers.size() == 1; + + // There may be more than one texture variable declared in the same + // statement: + // Texture2D<float> g_Tex2D1, g_Tex2D1; + do + { + // Texture2D TexName ; + // ^ + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::Identifier, "Identifier expected in ", TexDeclToken->Literal, " declaration" ); + + // Make sure there is a delimiter between sampler keyword and the + // identifier. In cases like this + // Texture2D<float>Name; + // There will be no whitespace + if( Token->Delimiter == "" ) + Token->Delimiter = " "; + + // Texture2D TexName ; + // ^ + const auto &TextureName = Token->Literal; + + auto CompleteGLSLSampler = GLSLSampler; + if( !IsRWTexture ) + { + // Try to find matching sampler + auto SamplerName = TextureName + "_sampler"; + // Search all scopes starting with the innermost + for( auto ScopeIt = Samplers.rbegin(); ScopeIt != Samplers.rend(); ++ScopeIt ) + { + auto SamplerIt = ScopeIt->find( SamplerName ); + if( SamplerIt != ScopeIt->end() ) + { + if( SamplerIt->second ) + CompleteGLSLSampler.append( "Shadow" ); + break; + } + } + } + + // TexDeclToken + // | + // Texture2D TexName ; + // ^ + TexDeclToken->Literal = ""; + TexDeclToken->Literal.append( LayoutQualifier ); + if( IsGlobalScope ) + { + // Samplers and images in global scope must be declared uniform. + // Function arguments must not be declared uniform + TexDeclToken->Literal.append( "uniform " ); + } + TexDeclToken->Literal.append( CompleteGLSLSampler ); + Objects.insert( std::make_pair( HashMapStringKey(TextureName), HLSLObjectInfo(CompleteGLSLSampler, NumComponents) ) ); + + // In global sceop, multiple variables can be declared in the same statement + if( IsGlobalScope ) + { + // Texture2D TexName, TexName2 ; + // ^ + + // Go to the next texture in the declaration or to the statement end + while( Token != m_Tokens.end() && Token->Type != TokenType::Comma && Token->Type != TokenType::Semicolon ) + ++Token; + if( Token->Type == TokenType::Comma ) + { + // Texture2D TexName, TexName2 ; + // ^ + Token->Type = TokenType::Semicolon; + Token->Literal = ";"; + // Texture2D TexName; TexName2 ; + // ^ + + ++Token; + // Texture2D TexName; TexName2 ; + // ^ + + // Insert empty token that will contain next sampler/image declaration + TexDeclToken = m_Tokens.insert( Token, TokenInfo(TextureType, "", "\n") ); + // Texture2D TexName; + // <Texture Declaration TBD> TexName2 ; + // ^ ^ + // TexDeclToken Token + } + else + { + // Texture2D TexName, TexName2 ; + // ^ + ++Token; + break; + } + } + + } while( IsGlobalScope && Token != m_Tokens.end() ); + +#undef SKIP_DELIMITER +#undef CHECK_EOF +} + + +// Finds an HLSL object with the given name in object stack +const HLSL2GLSLConverter::HLSLObjectInfo *HLSL2GLSLConverter::FindHLSLObject( const String &Name ) +{ + for( auto ScopeIt = m_Objects.rbegin(); ScopeIt != m_Objects.rend(); ++ScopeIt ) + { + auto It = ScopeIt->find( Name.c_str() ); + if( It != ScopeIt->end() ) + return &It->second; + } + return nullptr; +} + +Uint32 HLSL2GLSLConverter::CountFunctionArguments( TokenListType::iterator &Token, const TokenListType::iterator &ScopeEnd ) +{ + Uint32 NumArguments = 0; + int NumOpenBrackets = 1; + ++Token; + while( Token != ScopeEnd && NumOpenBrackets != 0 ) + { + // Do not count arguments of nested functions: + // TestText.Sample( TestText_sampler, float2(0.0, 1.0) ); + // ^ + // NumOpenBrackets == 2 + if( NumOpenBrackets == 1 && (Token->Literal == "," || Token->Type == TokenType::ClosingBracket) ) + ++NumArguments; + + if( Token->Type == TokenType::OpenBracket ) + ++NumOpenBrackets; + else if( Token->Type == TokenType::ClosingBracket ) + --NumOpenBrackets; + + ++Token; + } + return NumArguments; +} + +// The function processes HLSL object method in current scope and replaces it +// with the corresponding GLSL function stub +// Example: +// Texture2D<float2> Tex2D; +// ... +// Tex2D.Sample(Tex2D_sampler, f2UV) -> Sample_2(Tex2D, Tex2D_sampler, f2UV)_SWIZZLE2 +bool HLSL2GLSLConverter::ProcessObjectMethod(TokenListType::iterator &Token, + const TokenListType::iterator &ScopeStart, + const TokenListType::iterator &ScopeEnd) +{ + // TestText.Sample( ... + // ^ + // DotToken + auto DotToken = Token; + VERIFY_EXPR(DotToken != ScopeEnd && Token->Literal == "."); + auto MethodToken = DotToken; + ++MethodToken; + VERIFY_EXPR( MethodToken != ScopeEnd && MethodToken->Type == TokenType::Identifier); + // TestText.Sample( ... + // ^ + // MethodToken + auto IdentifierToken = DotToken; + // m_Tokens contains dummy node at the beginning, so we can + // check for ScopeStart to break the loop + while( IdentifierToken != ScopeStart && IdentifierToken->Type != TokenType::Identifier) + --IdentifierToken; + if( IdentifierToken == ScopeStart ) + return false; + // TestTextArr[2].Sample( ... + // ^ + // IdentifierToken + + // Try to find identifier + const auto *pObjectInfo = FindHLSLObject(IdentifierToken->Literal); + if( pObjectInfo == nullptr ) + { + return false; + } + const auto &ObjectType = pObjectInfo->GLSLType; + + auto ArgsListStartToken = MethodToken; + ++ArgsListStartToken; + + // TestText.Sample( ... + // ^ + // ArgsListStartToken + + if( ArgsListStartToken == ScopeEnd || ArgsListStartToken->Type != TokenType::OpenBracket ) + return false; + auto ArgsListEndToken = ArgsListStartToken; + Uint32 NumArguments = CountFunctionArguments( ArgsListEndToken, ScopeEnd ); + + if( ArgsListEndToken == ScopeEnd ) + return false; + // TestText.Sample( TestText_sampler, float2(0.0, 1.0) ); + // ^ + // ArgsListEndToken + auto Stub = m_GLSLStubs.find( FunctionStubHashKey(ObjectType, MethodToken->Literal.c_str(), NumArguments) ); + if( Stub == m_GLSLStubs.end() ) + { + LOG_ERROR_MESSAGE( "Unable to find function stub for ", IdentifierToken->Literal, ".", MethodToken->Literal, "(", NumArguments, " args). GLSL object type: ", ObjectType ); + return false; + } + + // DotToken + // V + // TestTextArr[2].Sample( TestTextArr_sampler, ... + // ^ ^ + // IdentifierToken ArgsListStartToken + + *ArgsListStartToken = TokenInfo(TokenType::Comma, ","); + // TestTextArr[2].Sample, TestTextArr_sampler, ... + // ^ ^ + // DotToken ArgsListStartToken + + m_Tokens.erase(DotToken, ArgsListStartToken); + // TestTextArr[2], TestTextArr_sampler, ... + // ^ + // IdentifierToken + + m_Tokens.insert( IdentifierToken, TokenInfo( TokenType::Identifier, Stub->second.Name.c_str(), IdentifierToken->Delimiter.c_str()) ); + IdentifierToken->Delimiter = " "; + // FunctionStub TestTextArr[2], TestTextArr_sampler, ... + // ^ + // IdentifierToken + + + m_Tokens.insert( IdentifierToken, TokenInfo( TokenType::OpenBracket, "(") ); + // FunctionStub( TestTextArr[2], TestTextArr_sampler, ... + // ^ + // IdentifierToken + + Token = ArgsListStartToken; + // FunctionStub( TestTextArr[2], TestTextArr_sampler, ... + // ^ + // Token + + // Nested function calls will be automatically processed: + // FunctionStub( TestTextArr[2], TestTextArr_sampler, TestTex.Sample(... + // ^ + // Token + + + // Add swizzling if there is any + if( Stub->second.Swizzle.length() > 0 ) + { + // FunctionStub( TestTextArr[2], TestTextArr_sampler, ... ); + // ^ + // ArgsListEndToken + + auto SwizzleToken = m_Tokens.insert( ArgsListEndToken, TokenInfo(TokenType::TextBlock, Stub->second.Swizzle.c_str(), "") ); + SwizzleToken->Literal.push_back( '0' + pObjectInfo->NumComponents ); + // FunctionStub( TestTextArr[2], TestTextArr_sampler, ... )_SWIZZLE4; + // ^ + // ArgsListEndToken + } + return true; +} + +void HLSL2GLSLConverter::RemoveFlowControlAttribute( TokenListType::iterator &Token ) +{ + VERIFY_EXPR( Token->Type == TokenType::FlowControl ); + // [ branch ] if ( ... + // ^ + auto PrevToken = Token; + --PrevToken; + // [ branch ] if ( ... + // ^ + // Note that dummy empty token is inserted into the beginning of the list + if( PrevToken == m_Tokens.begin() || PrevToken->Type != TokenType::ClosingStaple ) + return; + + --PrevToken; + // [ branch ] if ( ... + // ^ + if( PrevToken == m_Tokens.begin() || PrevToken->Type != TokenType::Identifier ) + return; + + --PrevToken; + // [ branch ] if ( ... + // ^ + if( PrevToken == m_Tokens.begin() || PrevToken->Type != TokenType::OpenStaple ) + return; + + // [ branch ] if ( ... + // ^ ^ + // PrevToken Token + Token->Delimiter = PrevToken->Delimiter; + m_Tokens.erase( PrevToken, Token ); +} + +// The function finds all HLSL object methods in the current scope and calls ProcessObjectMethod() +// that replaces them with the corresponding GLSL function stub. +void HLSL2GLSLConverter::ProcessObjectMethods(const TokenListType::iterator &ScopeStart, + const TokenListType::iterator &ScopeEnd) +{ + auto Token = ScopeStart; + while( Token != ScopeEnd ) + { + // Search for .identifier pattern + + if( Token->Literal == "." ) + { + auto DotToken = Token; + ++Token; + if( Token == ScopeEnd ) + break; + if( Token->Type == TokenType::Identifier ) + { + if( ProcessObjectMethod( DotToken, ScopeStart, ScopeEnd ) ) + Token = DotToken; + } + else + { + ++Token; + continue; + } + } + else + ++Token; + } +} + +// The function processes HLSL RW texture operator [] and replaces it with +// corresponding imageStore GLSL function. +// Example: +// RWTex[Location] = f3Value -> imageStore( RWTex,Location, _ExpandVector(f3Value)) +// _ExpandVector() function expands any input vector to 4-component vector +bool HLSL2GLSLConverter::ProcessRWTextureStore( TokenListType::iterator &Token, + const TokenListType::iterator &ScopeEnd ) +{ + // RWTex[Location.x] = float4(0.0, 0.0, 0.0, 1.0); + // ^ + auto AssignmentToken = Token; + while( AssignmentToken != ScopeEnd && + !(AssignmentToken->Type == TokenType::Assignment || AssignmentToken->Type == TokenType::Semicolon) ) + ++AssignmentToken; + + // The function is called for ALL RW texture objects found, so this may not be + // the store operation, but something else (for instance: + // InterlockedExchange(Tex2D_I1[GTid.xy], 1, iOldVal) ) + if( AssignmentToken == ScopeEnd || AssignmentToken->Type != TokenType::Assignment ) + return false; + // RWTex[Location.x] = float4(0.0, 0.0, 0.0, 1.0); + // ^ + // AssignmentToken + auto ClosingStaplePos = AssignmentToken; + while( ClosingStaplePos != Token && ClosingStaplePos->Type != TokenType::ClosingStaple ) + --ClosingStaplePos; + if( ClosingStaplePos == Token ) + return false; + // RWTex[Location.x] = float4(0.0, 0.0, 0.0, 1.0); + // ^ + // ClosingStaplePos + + auto OpenStaplePos = ClosingStaplePos; + while( OpenStaplePos != Token && OpenStaplePos->Type != TokenType::OpenStaple ) + --OpenStaplePos; + if( OpenStaplePos == Token ) + return false; + // RWTex[Location.x] = float4(0.0, 0.0, 0.0, 1.0); + // ^ + // OpenStaplePos + + auto SemicolonToken = AssignmentToken; + while( SemicolonToken != ScopeEnd && SemicolonToken->Type != TokenType::Semicolon ) + ++SemicolonToken; + if( SemicolonToken == ScopeEnd ) + return false; + // RWTex[Location.x] = float4(0.0, 0.0, 0.0, 1.0); + // ^ ^ + // Token SemicolonToken + + m_Tokens.insert( Token, TokenInfo(TokenType::Identifier, "imageStore", Token->Delimiter.c_str()) ); + m_Tokens.insert( Token, TokenInfo(TokenType::OpenBracket, "(", "" ) ); + Token->Delimiter = " "; + // imageStore( RWTex[Location.x] = float4(0.0, 0.0, 0.0, 1.0); + + OpenStaplePos->Delimiter = ""; + OpenStaplePos->Type = TokenType::Comma; + OpenStaplePos->Literal = ","; + // imageStore( RWTex,Location.x] = float4(0.0, 0.0, 0.0, 1.0); + // ^ + // ClosingStaplePos + + auto LocationToken = OpenStaplePos; + ++LocationToken; + m_Tokens.insert( LocationToken, TokenInfo( TokenType::Identifier, "_ToIvec", " " ) ); + m_Tokens.insert( LocationToken, TokenInfo( TokenType::OpenBracket, "(", "" ) ); + // imageStore( RWTex, _ToIvec(Location.x] = float4(0.0, 0.0, 0.0, 1.0); + // ^ + // ClosingStaplePos + + m_Tokens.insert( ClosingStaplePos, TokenInfo( TokenType::ClosingBracket, ")", "" ) ); + // imageStore( RWTex, _ToIvec(Location.x)] = float4(0.0, 0.0, 0.0, 1.0); + // ^ + // ClosingStaplePos + + ClosingStaplePos->Delimiter = ""; + ClosingStaplePos->Type = TokenType::Comma; + ClosingStaplePos->Literal = ","; + // imageStore( RWTex, _ToIvec(Location.x), = float4(0.0, 0.0, 0.0, 1.0); + // ^ + // AssignmentToken + + AssignmentToken->Delimiter = ""; + AssignmentToken->Type = TokenType::OpenBracket; + AssignmentToken->Literal = "("; + // imageStore( RWTex, _ToIvec(Location.x),( float4(0.0, 0.0, 0.0, 1.0); + // ^ + + m_Tokens.insert( AssignmentToken, TokenInfo(TokenType::Identifier, "_ExpandVector", " " ) ); + // imageStore( RWTex, _ToIvec(Location.x), _ExpandVector( float4(0.0, 0.0, 0.0, 1.0); + // ^ + + // Insert closing bracket for _ExpandVector + m_Tokens.insert( SemicolonToken, TokenInfo(TokenType::ClosingBracket, ")", "" ) ); + // imageStore( RWTex, _ToIvec(Location.x), _ExpandVector( float4(0.0, 0.0, 0.0, 1.0)); + + // Insert closing bracket for imageStore + m_Tokens.insert( SemicolonToken, TokenInfo(TokenType::ClosingBracket, ")", "" ) ); + // imageStore( RWTex, _ToIvec(Location.x), _ExpandVector( float4(0.0, 0.0, 0.0, 1.0))); + + return false; +} + +// Function finds all RW textures in current scope and calls ProcessRWTextureStore() +// that detects if this is store operation and converts it to imageStore() +void HLSL2GLSLConverter::ProcessRWTextures(const TokenListType::iterator &ScopeStart, + const TokenListType::iterator &ScopeEnd) +{ + auto Token = ScopeStart; + while( Token != ScopeEnd ) + { + if( Token->Type == TokenType::Identifier ) + { + // Try to find the object in all scopes + const auto *pObjectInfo = FindHLSLObject(Token->Literal); + if( pObjectInfo == nullptr ) + { + ++Token; + continue; + } + + // Check if the object is image type + auto ImgTypeIt = m_ImageTypes.find( pObjectInfo->GLSLType.c_str() ); + if( ImgTypeIt == m_ImageTypes.end() ) + { + ++Token; + continue; + } + + // Handle store. If this is not store operation, + // ProcessRWTextureStore() returns false. + auto TmpToken = Token; + if( ProcessRWTextureStore( TmpToken, ScopeEnd ) ) + Token = TmpToken; + else + ++Token; + } + else + ++Token; + } +} + +// The function processes all atomic operations in current scope and replaces them with +// corresponding GLSL function +void HLSL2GLSLConverter::ProcessAtomics(const TokenListType::iterator &ScopeStart, + const TokenListType::iterator &ScopeEnd) +{ + auto Token = ScopeStart; + while( Token != ScopeEnd ) + { + if( Token->Type == TokenType::Identifier ) + { + auto AtomicIt = m_AtomicOperations.find(Token->Literal.c_str()); + if( AtomicIt == m_AtomicOperations.end() ) + { + ++Token; + continue; + } + + auto OperationToken = Token; + // InterlockedAdd(g_i4SharedArray[GTid.x].x, 1, iOldVal); + // ^ + ++Token; + // InterlockedAdd(g_i4SharedArray[GTid.x].x, 1, iOldVal); + // ^ + VERIFY_PARSER_STATE( Token, Token != ScopeEnd, "Unexpected EOF" ); + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::OpenBracket, "Open bracket is expected" ); + + ++Token; + // InterlockedAdd(g_i4SharedArray[GTid.x].x, 1, iOldVal); + // ^ + VERIFY_PARSER_STATE( Token, Token != ScopeEnd, "Unexpected EOF" ); + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::Identifier, "Identifier is expected" ); + + auto ArgsListEndToken = Token; + auto NumArguments = CountFunctionArguments( ArgsListEndToken, ScopeEnd ); + // InterlockedAdd(Tex2D[GTid.xy], 1, iOldVal); + // ^ + // ArgsListEndToken + VERIFY_PARSER_STATE( ArgsListEndToken, ArgsListEndToken != ScopeEnd, "Unexpected EOF" ); + + const auto *pObjectInfo = FindHLSLObject(Token->Literal); + if( pObjectInfo != nullptr ) + { + // InterlockedAdd(Tex2D[GTid.xy], 1, iOldVal); + // ^ + auto Stub = m_GLSLStubs.find( FunctionStubHashKey("image", OperationToken->Literal.c_str(), NumArguments) ); + VERIFY_PARSER_STATE(OperationToken, Stub != m_GLSLStubs.end(), "Unable to find function stub for funciton ", OperationToken->Literal, " with ", NumArguments, " arguments" ); + + // Find first comma + int NumOpenBrackets = 1; + while( Token != ScopeEnd && NumOpenBrackets != 0 ) + { + // Do not count arguments of nested functions: + if( NumOpenBrackets == 1 && (Token->Type == TokenType::Comma || Token->Type == TokenType::ClosingBracket) ) + break; + + if( Token->Type == TokenType::OpenBracket ) + ++NumOpenBrackets; + else if( Token->Type == TokenType::ClosingBracket ) + --NumOpenBrackets; + + ++Token; + } + // InterlockedAdd(Tex2D[GTid.xy], 1, iOldVal); + // ^ + VERIFY_PARSER_STATE( Token, Token != ScopeEnd, "Unexpected EOF" ); + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::Comma, "Comma is expected" ); + + --Token; + // InterlockedAdd(Tex2D[GTid.xy], 1, iOldVal); + // ^ + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::ClosingStaple, "Expected \']\'" ); + auto ClosingBracketToken = Token; + --Token; + m_Tokens.erase( ClosingBracketToken ); + // InterlockedAdd(Tex2D[GTid.xy, 1, iOldVal); + // ^ + while( Token != ScopeStart && Token->Type != TokenType::OpenStaple ) + --Token; + // InterlockedAdd(Tex2D[GTid.xy, 1, iOldVal); + // ^ + + VERIFY_PARSER_STATE( Token, Token != ScopeStart, "Expected \'[\'" ); + Token->Type = TokenType::Comma; + Token->Literal = ","; + // InterlockedAdd(Tex2D,GTid.xy, 1, iOldVal); + // ^ + + OperationToken->Literal = Stub->second.Name; + // InterlockedAddImage_3(Tex2D,GTid.xy, 1, iOldVal); + } + else + { + // InterlockedAdd(g_i4SharedArray[GTid.x].x, 1, iOldVal); + // ^ + auto Stub = m_GLSLStubs.find( FunctionStubHashKey("shared_var", OperationToken->Literal.c_str(), NumArguments) ); + VERIFY_PARSER_STATE(OperationToken, Stub != m_GLSLStubs.end(), "Unable to find function stub for funciton ", OperationToken->Literal, " with ", NumArguments, " arguments" ); + OperationToken->Literal = Stub->second.Name; + // InterlockedAddSharedVar_3(g_i4SharedArray[GTid.x].x, 1, iOldVal); + } + Token = ArgsListEndToken; + } + else + ++Token; + } +} + +// The function parses shader arguments and puts them into Params array +void HLSL2GLSLConverter::ParseShaderParameters( TokenListType::iterator &Token, std::vector<ShaderParameterInfo>& Params ) +{ + // void TestPS ( in VSOutput In, + // ^ + VERIFY_EXPR(Token->Type == TokenType::OpenBracket); + ++Token; + // void TestPS ( in VSOutput In, + // ^ + while(Token != m_Tokens.end()) + { + ShaderParameterInfo ParamInfo; + if( Token->Literal == "in" ) + { + //void TestPS ( in VSOutput In, + // ^ + ParamInfo.storageQualifier = ShaderParameterInfo::StorageQualifier::In; + ++Token; + //void TestPS ( in VSOutput In, + // ^ + } + else if( Token->Literal == "out" ) + { + // out float4 Color : SV_Target, + // ^ + ParamInfo.storageQualifier = ShaderParameterInfo::StorageQualifier::Out; + ++Token; + // out float4 Color : SV_Target, + // ^ + } + else + ParamInfo.storageQualifier = ShaderParameterInfo::StorageQualifier::In; + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected EOF while parsing argument list" ); + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::BuiltInType || Token->Type == TokenType::Identifier, + "Missing argument type" ); + + ParamInfo.Type = Token->Literal; + + ++Token; + // out float4 Color : SV_Target, + // ^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected EOF while parsing argument list" ); + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::Identifier, "Missing argument name after ", ParamInfo.Type ); + ParamInfo.Name = Token->Literal; + + ++Token; + // out float4 Color : SV_Target, + // ^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected end of file after argument \"", ParamInfo.Name, '\"' ); + if( Token->Literal == ":" ) + { + ++Token; + // out float4 Color : SV_Target, + // ^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected end of file while looking for semantic for argument \"", ParamInfo.Name, '\"' ); + VERIFY_PARSER_STATE( Token, Token->Type == TokenType::Identifier, "Missing semantic for argument \"", ParamInfo.Name, '\"' ); + ParamInfo.Semantic = Token->Literal; + // Transform to lower case - semantics are case-insensitive + std::transform( ParamInfo.Semantic.begin(), ParamInfo.Semantic.end(), ParamInfo.Semantic.begin(), ::tolower ); + + ++Token; + // out float4 Color : SV_Target, + // ^ + } + + VERIFY_PARSER_STATE( Token, Token->Literal == "," || Token->Type == TokenType::ClosingBracket, "\',\' or \')\' is expected after argument \"", ParamInfo.Name, '\"' ); + Params.push_back( ParamInfo ); + if( Token->Type == TokenType::ClosingBracket ) + break; + ++Token; + } +} + +void DeclareVariable(const String& Type, const String& Name, const Char* InitValue, bool bForceType, std::stringstream &OutSS) +{ + OutSS << Type << ' ' << Name; + if( InitValue ) + { + OutSS << " = "; + if( bForceType ) + { + OutSS << Type << '('; + } + OutSS << InitValue; + if( bForceType ) + OutSS << ')'; + } + OutSS << ";\n" ; +} + +void DeclareInterfaceBlock( const Char* Qualifier, Uint32 InterfaceBlockNum, const String& ParamType, const String& ParamName, std::stringstream &OutSS ) +{ + OutSS << Qualifier <<" _IntererfaceBlock" << InterfaceBlockNum << "\n" + "{\n" + " " << ParamType << ' ' << ParamName << ";\n" + "};\n"; +} + +void HLSL2GLSLConverter::ProcessFragmentShaderArguments(std::vector<ShaderParameterInfo>& Params, + String &GlobalVariables, + String &Epilogue, + String &Prologue) +{ + stringstream GlobalVarsSS, PrologueSS, EpilogueSS; + int InterfaceBlockNum = 0; + for( const auto &Param : Params ) + { + if( Param.storageQualifier == ShaderParameterInfo::StorageQualifier::In ) + { + if( Param.Semantic == "" ) + { + DeclareInterfaceBlock( "in", InterfaceBlockNum, Param.Type, Param.Name, GlobalVarsSS ); + ++InterfaceBlockNum; + } + else if( Param.Semantic == "sv_position" ) + { + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), "gl_FragCoord", false, PrologueSS ); + } + else + { + LOG_ERROR_AND_THROW( "Semantic \"", Param.Semantic, "\" is not supported in a pixel shader." ); + } + } + else if( Param.storageQualifier == ShaderParameterInfo::StorageQualifier::Out ) + { + const auto& Semantic = Param.Semantic; + auto RTIndexPos = Semantic.begin(); + int RTIndex = -1; + if( SkipPrefix( "sv_target", RTIndexPos, Semantic.end() ) ) + { + if( RTIndexPos != Semantic.end() ) + { + if( *RTIndexPos >= '0' && *RTIndexPos <= '9' ) + { + RTIndex = *RTIndexPos - '0'; + if( (RTIndexPos + 1) != Semantic.end() ) + RTIndex = -1; + } + } + else + RTIndex = 0; + } + + if( RTIndex >= 0 && RTIndex < MaxRenderTargets ) + { + String GlobalVarName = "_out_"; + GlobalVarName.append( Param.Name ); + + GlobalVarsSS << "layout(location = " << RTIndex << ") out " + << Param.Type << ' ' << GlobalVarName << ";\n"; + + DeclareVariable( Param.Type, Param.Name, nullptr, false, PrologueSS ); + + EpilogueSS << GlobalVarName << " = " << Param.Name << ";\n"; + } + else + { + LOG_ERROR_AND_THROW( "Unexpected output semantic \"", Semantic, "\". The only allowed output semantic for fragment shader is SV_Target*" ); + } + } + } + GlobalVariables = GlobalVarsSS.str(); + Prologue = PrologueSS.str(); + Epilogue = EpilogueSS.str(); +} + + +void HLSL2GLSLConverter::ProcessVertexShaderArguments( std::vector<ShaderParameterInfo>& Params, + String &GlobalVariables, + String &Epilogue, + String &Prologue ) +{ + stringstream GlobalVarsSS, PrologueSS, EpilogueSS; + GlobalVarsSS << + "\n" + "#ifndef GL_ES\n" + "out gl_PerVertex\n" + "{\n" + " vec4 gl_Position;\n" + "};\n" + "#endif\n"; + int InterfaceBlockNum = 0; + for( const auto &Param : Params ) + { + const auto& Semantic = Param.Semantic; + if( Param.storageQualifier == ShaderParameterInfo::StorageQualifier::In ) + { + auto SemanticEndPos = Semantic.begin(); + if( SkipPrefix( "attrib", SemanticEndPos, Semantic.end() ) ) + { + char* EndPtr = nullptr; + auto InputLocation = strtol(&*SemanticEndPos, &EndPtr, 10); + if( EndPtr == nullptr || *EndPtr != 0 ) + { + LOG_ERROR_AND_THROW( "Unexpected input semantic \"", Semantic, "\". The only allowed semantic for the vertex shader input attributes is ATTRIB*" ); + } + + String GlobalVarName = "_in_"; + GlobalVarName.append( Param.Name ); + GlobalVarsSS << "layout(location = " << InputLocation << ") in " + << Param.Type << ' ' << GlobalVarName << ";\n"; + + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), GlobalVarName.c_str(), false, PrologueSS ); + } + else if( Semantic == "sv_vertexid" ) + { + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), "gl_VertexID", true, PrologueSS ); + } + else if( Semantic == "sv_instanceid" ) + { + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), "gl_InstanceID", true, PrologueSS ); + } + else + { + LOG_ERROR_AND_THROW( "Unexpected input semantic \"", Semantic, "\". The only allowed semantics for the vertex shader inputs are \"ATTRIB*\", \"SV_VertexID\", and \"SV_InstanceID\"." ); + } + } + else if( Param.storageQualifier == ShaderParameterInfo::StorageQualifier::Out ) + { + if( Semantic == "" ) + { + // Should be struct + DeclareInterfaceBlock( "out", InterfaceBlockNum, Param.Type, Param.Name, GlobalVarsSS ); + ++InterfaceBlockNum; + } + else if( Semantic == "sv_position" ) + { + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), nullptr, false, PrologueSS ); + EpilogueSS << "gl_Position = " << Param.Name << ";\n" ; + } + else + { + LOG_ERROR_AND_THROW( "Unexpected output semantic \"", Semantic, "\". The only allowed semantic for the vertex shader output is \"SV_Position\"." ); + } + } + } + GlobalVariables = GlobalVarsSS.str(); + Prologue = PrologueSS.str(); + Epilogue = EpilogueSS.str(); +} + + +void HLSL2GLSLConverter::ProcessComputeShaderArguments( TokenListType::iterator &TypeToken, + std::vector<ShaderParameterInfo>& Params, + String &GlobalVariables, + String &Prologue ) +{ + stringstream GlobalVarsSS, PrologueSS; + + auto Token = TypeToken; + //[numthreads(16,16,1)] + //void TestCS(uint3 DTid : SV_DispatchThreadID) + //^ + --Token; + //[numthreads(16,16,1)] + // ^ + //void TestCS(uint3 DTid : SV_DispatchThreadID) + VERIFY_PARSER_STATE( Token, Token != m_Tokens.begin() && Token->Type == TokenType::ClosingStaple, "Missing numthreads declaration"); + + while( Token != m_Tokens.begin() && Token->Type != TokenType::OpenStaple ) + --Token; + //[numthreads(16,16,1)] + //^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.begin(), "Missing numthreads() declaration"); + auto OpenStapleToken = Token; + + ++Token; + //[numthreads(16,16,1)] + // ^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end() && Token->Type == TokenType::Identifier && Token->Literal == "numthreads", + "Missing numthreads() declaration" ); + + ++Token; + //[numthreads(16,16,1)] + // ^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end() && Token->Type == TokenType::OpenBracket, + "Missing \'(\' after numthreads" ); + + String CSGroupSize[3] = {}; + static const Char *DirNames[] = { "X", "Y", "Z" }; + for( int i = 0; i < 3; ++i ) + { + ++Token; + //[numthreads(16,16,1)] + // ^ + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end() && (Token->Type == TokenType::NumericConstant || Token->Type == TokenType::Identifier), + "Missing group size for ", DirNames[i], " direction" ); + CSGroupSize[i] = Token->Literal.c_str(); + ++Token; + //[numthreads(16,16,1)] + // ^ ^ + const Char* ExpectedLiteral = (i < 2) ? "," : ")"; + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end() && Token->Literal == ExpectedLiteral, + "Missing \'", ExpectedLiteral, "\' after ", DirNames[i], " direction" ); + } + + //OpenStapleToken + //V + //[numthreads(16,16,1)] + //void TestCS(uint3 DTid : SV_DispatchThreadID) + //^ + //TypeToken + TypeToken->Delimiter = OpenStapleToken->Delimiter; + m_Tokens.erase( OpenStapleToken, TypeToken ); + // + // void TestCS(uint3 DTid : SV_DispatchThreadID) + + GlobalVarsSS << "layout ( local_size_x = " << CSGroupSize[0] + << ", local_size_y = " << CSGroupSize[1] << ", local_size_z = " << CSGroupSize[2] << " ) in;\n"; + + for( const auto &Param : Params ) + { + const auto& Semantic = Param.Semantic; + if( Param.storageQualifier == ShaderParameterInfo::StorageQualifier::In ) + { + auto SemanticEndPos = Semantic.begin(); + if( Semantic == "sv_dispatchthreadid" ) + { + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), "gl_GlobalInvocationID", true, PrologueSS ); + } + else if( Semantic == "sv_groupid" ) + { + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), "gl_WorkGroupID", true, PrologueSS ); + } + else if( Semantic == "sv_groupthreadid" ) + { + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), "gl_LocalInvocationID", true, PrologueSS ); + } + else if( Semantic == "sv_groupindex" ) + { + DeclareVariable( Param.Type.c_str(), Param.Name.c_str(), "gl_LocalInvocationIndex", true, PrologueSS ); + } + else + { + LOG_ERROR_AND_THROW( "Unexpected input semantic \"", Semantic, "\". The only allowed semantics for the vertex shader inputs are \"ATTRIB*\", \"SV_VertexID\", and \"SV_InstanceID\"." ); + } + } + else if( Param.storageQualifier == ShaderParameterInfo::StorageQualifier::Out ) + { + LOG_ERROR_AND_THROW( "Output variables are not allowed in compute shaders" ); + } + } + + GlobalVariables = GlobalVarsSS.str(); + Prologue = PrologueSS.str(); +} + +void HLSL2GLSLConverter::ProcessReturnStatements( TokenListType::iterator &Token, const String &Epilogue, const char *EntryPoint ) +{ + VERIFY_EXPR( Token->Type == TokenType::OpenBrace ); + + ++Token; // Skip open brace + int BraceCount = 1; + // Find matching closing brace + while( Token != m_Tokens.end() ) + { + if( Token->Type == TokenType::OpenBrace ) + ++BraceCount; + else if( Token->Type == TokenType::ClosingBrace ) + { + --BraceCount; + if( BraceCount == 0 ) + break; + } + else if( Token->Type == TokenType::FlowControl ) + { + if( Token->Literal == "return" ) + { + //if( x < 0.5 ) return; + // ^ + m_Tokens.insert( Token, TokenInfo(TokenType::OpenBrace, "{", "\r\n")); + Token->Delimiter = ""; + //if( x < 0.5 ) + //{return; + // ^ + + m_Tokens.insert(Token, TokenInfo(TokenType::TextBlock, Epilogue.c_str(), "\r\n")); + //if( x < 0.5 ) + //{ + //gl_Position = f4PosWS; + //return; + //^ + + while( Token->Type != TokenType::Semicolon ) + ++Token; + //if( x < 0.5 ) + //{ + //gl_Position = f4PosWS; + //return; + // ^ + + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected end of file while looking for the \';\'" ); + ++Token; + //if( x < 0.5 ) + //{ + //gl_Position = f4PosWS; + //return; + //float a; + //^ + + m_Tokens.insert( Token, TokenInfo(TokenType::ClosingBrace, "}", "\r\n") ); + //if( x < 0.5 ) + //{ + //gl_Position = f4PosWS; + //return; + //} + //int a; + //^ + + continue; + } + } + ++Token; + } + VERIFY_PARSER_STATE( Token, BraceCount == 0, "No matching closing bracket found" ); + + // void main () + // { + // ... + // } + // ^ + VERIFY_PARSER_STATE(Token, Token != m_Tokens.end(), "Unexpected end of file while looking for the end of body of shader entry point \"", EntryPoint, "\"." ); + VERIFY_EXPR( Token->Type == TokenType::ClosingBrace ); + // Insert epilogue before the closing brace + m_Tokens.insert(Token, TokenInfo(TokenType::TextBlock, Epilogue.c_str(), Token->Delimiter.c_str())); + Token->Delimiter = "\n"; +} + +void HLSL2GLSLConverter::ProcessShaderDeclaration( const Char* EntryPoint, SHADER_TYPE ShaderType ) +{ + auto EntryPointToken = m_Tokens.begin(); + int NumOpenBraces = 0; + while( EntryPointToken != m_Tokens.end() ) + { + if( EntryPointToken->Type == TokenType::OpenBrace ) + ++NumOpenBraces; + else if( EntryPointToken->Type == TokenType::ClosingBrace ) + { + --NumOpenBraces; + VERIFY_PARSER_STATE( EntryPointToken, NumOpenBraces >= 0, "Unexpected \'}\'"); + } + + // Search global scope only + if( NumOpenBraces == 0 && + EntryPointToken->Type == TokenType::Identifier && + EntryPointToken->Literal == EntryPoint ) + break; + ++EntryPointToken; + } + VERIFY_PARSER_STATE( EntryPointToken, EntryPointToken != m_Tokens.end(), "Unable to find shader entry point \"", EntryPoint,'\"' ); + // void TestPS ( in VSOutput In, + // ^ + // EntryPointToken + auto TypeToken = EntryPointToken; + --TypeToken; + // void TestPS ( in VSOutput In, + // ^ + // TypeToken + VERIFY_PARSER_STATE( TypeToken, TypeToken != m_Tokens.begin(), "Missing return type for shader entry point \"", EntryPoint,'\"' ); + VERIFY_PARSER_STATE( TypeToken, TypeToken->Literal == "void", "Unexpected return type \"", TypeToken->Literal, "\" for shader entry point \"", EntryPoint, "\"\n" + "Shader outputs should be declared as out parameters to the function."); + + auto ArgsListStartToken = EntryPointToken; + ++ArgsListStartToken; + // void TestPS ( in VSOutput In, + // ^ + // ArgsListStartToken + VERIFY_PARSER_STATE( ArgsListStartToken, ArgsListStartToken->Type == TokenType::OpenBracket, "Missing argument list for shader entry point \"", EntryPoint,'\"' ); + + std::vector<ShaderParameterInfo> ShaderParams; + auto ArgsListEndToken = ArgsListStartToken; + ParseShaderParameters( ArgsListEndToken, ShaderParams ); + + ++ArgsListStartToken; + // ArgsListStartToken + // V + //void TestPS ( in VSOutput In, + // out float4 Color : SV_Target, + // out float3 Color2 : SV_Target2 ) + // ^ + // ArgsListEndToken + + m_Tokens.erase(ArgsListStartToken, ArgsListEndToken); + //void TestPS () + EntryPointToken->Literal = "main"; + //void main () + + String GlobalVariables, Epilogue, Prologue; + try + { + if( ShaderType == SHADER_TYPE_PIXEL ) + { + ProcessFragmentShaderArguments( ShaderParams, GlobalVariables, Epilogue, Prologue ); + } + else if( ShaderType == SHADER_TYPE_VERTEX ) + { + ProcessVertexShaderArguments( ShaderParams, GlobalVariables, Epilogue, Prologue ); + } + else if( ShaderType == SHADER_TYPE_COMPUTE ) + { + ProcessComputeShaderArguments( TypeToken, ShaderParams, GlobalVariables, Prologue ); + } + } + catch( const std::runtime_error & ) + { + LOG_ERROR_AND_THROW( "Failed to process shader parameters for shader \"", EntryPoint, "\"." ); + } + + + // void main () + // ^ + // TypeToken + + // Insert global variables before the function + m_Tokens.insert(TypeToken, TokenInfo(TokenType::TextBlock, GlobalVariables.c_str(), TypeToken->Delimiter.c_str())); + TypeToken->Delimiter = "\n"; + auto BodyStartToken = ArgsListEndToken; + while( BodyStartToken != m_Tokens.end() && BodyStartToken->Type != TokenType::OpenBrace ) + ++BodyStartToken; + // void main () + // { + // ^ + VERIFY_PARSER_STATE(BodyStartToken, BodyStartToken != m_Tokens.end(), "Unexpected end of file while looking for the body of shader entry point \"", EntryPoint, "\"." ); + auto FirstStatementToken = BodyStartToken; + ++FirstStatementToken; + // void main () + // { + // int a; + // ^ + VERIFY_PARSER_STATE(FirstStatementToken, FirstStatementToken != m_Tokens.end(), "Unexpected end of file while looking for the body of shader entry point \"", EntryPoint, "\"." ); + + // Insert prologue before the first token + m_Tokens.insert(FirstStatementToken, TokenInfo(TokenType::TextBlock, Prologue.c_str(), "\n")); + + if( Epilogue.length() > 0 ) + { + auto BodyEndToken = BodyStartToken; + ProcessReturnStatements( BodyEndToken, Epilogue, EntryPoint ); + } +} + + +void HLSL2GLSLConverter::RemoveSemanticsFromBlock(TokenListType::iterator &Token, TokenType OpenBracketType, TokenType ClosingBracketType, bool IsStruct) +{ + VERIFY_EXPR( Token->Type == OpenBracketType ); + + int NumOpenBrackets = 0; + while( Token != m_Tokens.end() ) + { + if( Token->Type == OpenBracketType ) + ++NumOpenBrackets; + else if( Token->Type == ClosingBracketType ) + --NumOpenBrackets; + + if( Token->Literal == ":" ) + { + // float4 Pos : POSITION; + // ^ + auto ColonToken = Token; + ++Token; + // float4 Pos : POSITION; + // ^ + if( Token->Type == TokenType::Identifier ) + { + auto SemanticToken = Token; + ++Token; + // float4 Pos : POSITION; + // ^ + + // float4 Pos : POSITION, Normal : NORMAL; + // ^ + + // float4 Pos : POSITION) + // ^ + if( Token->Type == TokenType::Semicolon || Token->Literal == "," || Token->Type == TokenType::ClosingBracket ) + { + if( IsStruct ) + { + auto TmpIt = SemanticToken->Literal.begin(); + auto IsSVSemantic = SkipPrefix( "SV_", TmpIt, SemanticToken->Literal.end() ); + VERIFY_PARSER_STATE(SemanticToken, !IsSVSemantic, "System-value semantics are not allowed in structures. Please make this explicit input/output to the shader") + } + m_Tokens.erase( ColonToken, Token ); + // float4 Pos ; + // ^ + } + } + } + else + ++Token; + + if( NumOpenBrackets == 0 ) + break; + } + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected EOF while parsing body of the structure" ); +} + +void HLSL2GLSLConverter::RemoveSemantics() +{ + auto Token = m_Tokens.begin(); + int NumOpenBraces = 0; + while( Token != m_Tokens.end() ) + { + if( Token->Type == TokenType::OpenBrace ) + ++NumOpenBraces; + else if( Token->Type == TokenType::ClosingBrace ) + --NumOpenBraces; + + // Search global scope only + if( NumOpenBraces == 0 ) + { + if( Token->Type == TokenType::_struct ) + { + //struct MyStruct + //^ + while( Token != m_Tokens.end() && Token->Type != TokenType::OpenBrace ) + ++Token; + + VERIFY_PARSER_STATE( Token, Token != m_Tokens.end(), "Unexpected EOF while searching for the structure body" ); + //struct MyStruct + //{ + //^ + RemoveSemanticsFromBlock( Token, TokenType::OpenBrace, TokenType::ClosingBrace, true ); + + // struct MyStruct + // { + // ... + // }; + // ^ + continue; + } + else if( Token->Type == TokenType::Identifier ) + { + // Searh for "Identifier(" pattern + // In global scope this should be texture declaration + // It can also be other things like macro. But this is not a problem. + ++Token; + if( Token == m_Tokens.end() ) + break; + if( Token->Type == TokenType::OpenBracket ) + { + RemoveSemanticsFromBlock( Token, TokenType::OpenBracket, TokenType::ClosingBracket, false ); + // void TestVS( ... ) + // { + // ^ + } + + continue; + } + } + + ++Token; + } +} + +// Remove special shader attributes such as [numthreads(16, 16, 1)] +void HLSL2GLSLConverter::RemoveSpecialShaderAttributes() +{ + auto Token = m_Tokens.begin(); + int NumOpenBraces = 0; + while( Token != m_Tokens.end() ) + { + if( Token->Type == TokenType::OpenBrace ) + ++NumOpenBraces; + else if( Token->Type == TokenType::ClosingBrace ) + --NumOpenBraces; + + // Search global scope only + if( NumOpenBraces == 0 ) + { + if( Token->Type == TokenType::OpenStaple ) + { + auto OpenStaple = Token; + ++Token; + if( Token == m_Tokens.end() ) + break; + if( Token->Literal == "numthreads" ) + { + ++Token; + if( Token->Type != TokenType::OpenBracket ) + continue; + while( Token != m_Tokens.end() && Token->Type != TokenType::ClosingStaple ) + ++Token; + if( Token != m_Tokens.end() ) + { + ++Token; + if( Token != m_Tokens.end() ) + Token->Delimiter = OpenStaple->Delimiter + Token->Delimiter; + m_Tokens.erase( OpenStaple, Token ); + continue; + } + } + } + } + ++Token; + } +} + +String HLSL2GLSLConverter::BuildGLSLSource() +{ + String Output; + for( const auto& Token : m_Tokens ) + { + Output.append( Token.Delimiter ); + Output.append( Token.Literal ); + } + return Output; +} + +void HLSL2GLSLConverter::ProcessScope( const TokenListType::iterator &ScopeStart, + const TokenListType::iterator &ScopeEnd ) +{ + VERIFY_EXPR( ScopeStart->Type == TokenType::OpenBrace && ScopeEnd->Type == TokenType::ClosingBrace ); + + ProcessObjectMethods(ScopeStart, ScopeEnd); + + ProcessRWTextures(ScopeStart, ScopeEnd); + + ProcessAtomics(ScopeStart, ScopeEnd); +} + +String HLSL2GLSLConverter::Convert( const Char* HLSLSource, size_t NumSymbols, const Char* EntryPoint, SHADER_TYPE ShaderType ) +{ + String GLSLSource(HLSLSource, NumSymbols); + + InsertIncludes( GLSLSource ); + + Tokenize(GLSLSource); + + std::unordered_map<String, bool> SamplersHash; + auto Token = m_Tokens.begin(); + // Process constant buffers, fix floating point constants and + // remove flow control attributes + while( Token != m_Tokens.end() ) + { + switch( Token->Type ) + { + case TokenType::cbuffer: + ProcessConstantBuffer( Token ); + break; + + case TokenType::NumericConstant: + // This all work is only required because some GLSL compilers are so stupid that + // flood shader output with insane warnings like this: + // WARNING: 0:259: Only GLSL version > 110 allows postfix "F" or "f" for float + // even when compiling for GL 4.3 AND the code IS UNDER #if 0 + if( Token->Literal.back() == 'f' || Token->Literal.back() == 'F' ) + Token->Literal.pop_back(); + ++Token; + break; + + case TokenType::FlowControl: + // Remove flow control attributes like [flatten], [branch], [loop], etc. + RemoveFlowControlAttribute( Token ); + ++Token; + break; + + default: + ++Token; + } + } + + // Process textures. GLSL does not allow local variables + // of sampler type, so the only two scopes where textures can + // be declared are global scope and a function argument list. + { + TokenListType::iterator FunctionStart = m_Tokens.end(); + std::vector< SamplerHashType > Samplers; + + // Find all samplers in the global scope + Samplers.emplace_back( SamplerHashType() ); + m_Objects.emplace_back( ObjectsTypeHashType() ); + Token = m_Tokens.begin(); + ParseSamplers( Token, Samplers.back() ); + VERIFY_EXPR( Token == m_Tokens.end() ); + + Int32 ScopeDepth = 0; + + Token = m_Tokens.begin(); + while( Token != m_Tokens.end() ) + { + // Detect global function declaration by looking for the pattern + // <return type> Identifier ( + // in global scope + if( ScopeDepth == 0 && Token->Type == TokenType::Identifier ) + { + // float4 Func ( in float2 f2UV, + // ^ + // Token + auto ReturnTypeToken = Token; + --ReturnTypeToken; + ++Token; + if( Token == m_Tokens.end() ) + break; + // ReturnTypeToken + // | + // float4 Func ( in float2 f2UV, + // ^ + // Token + if( (ReturnTypeToken->Type == TokenType::BuiltInType || + ReturnTypeToken->Type == TokenType::Identifier ) && + Token->Type == TokenType::OpenBracket ) + { + // Parse samplers in the function argument list + Samplers.emplace_back( SamplerHashType() ); + // GLSL does not support sampler variables, + // so the only place where a new sampler + // declaration is allowed is function argument + // list + auto ArgListEnd = Token; + ParseSamplers( ArgListEnd, Samplers.back() ); + // float4 Func ( in float2 f2UV ) + // ^ + // ArgListEnd + auto OpenBrace = ArgListEnd; + ++OpenBrace; + // float4 Func ( in float2 f2UV ) + // { + // ^ + if( OpenBrace->Type == TokenType::OpenBrace ) + { + // We need to go through the function argument + // list as there may be texture declaraions + ++Token; + // float4 Func ( in float2 f2UV, + // ^ + // Token + + // Put empty table on top of the object stack + m_Objects.emplace_back( ObjectsTypeHashType() ); + } + else + { + // For some reason there is no open brace after + // what should be argument list - pop the samplers + Samplers.pop_back(); + } + } + } + + if( Token->Type == TokenType::OpenBrace ) + { + if( Samplers.size() == 2 && ScopeDepth == 0 ) + { + VERIFY_EXPR( FunctionStart == m_Tokens.end() ); + // This is the first open brace after the + // Samplers stack has grown to two -> this is + // the beginning of a function body + FunctionStart = Token; + } + ++ScopeDepth; + ++Token; + } + else if( Token->Type == TokenType::ClosingBrace ) + { + --ScopeDepth; + if( Samplers.size() == 2 && ScopeDepth == 0 ) + { + // We are returning to the global scope now and + // the samplers stack size is 2 -> this was a function + // body. We need to process it now. + ProcessScope( FunctionStart, Token ); + // Pop function arguments from the sampler and object + // stacks + Samplers.pop_back(); + m_Objects.pop_back(); + FunctionStart = m_Tokens.end(); + } + ++Token; + } + else if( Token->Type == TokenType::Texture1D || + Token->Type == TokenType::Texture1DArray || + Token->Type == TokenType::Texture2D || + Token->Type == TokenType::Texture2DArray || + Token->Type == TokenType::Texture3D || + Token->Type == TokenType::TextureCube || + Token->Type == TokenType::TextureCubeArray || + Token->Type == TokenType::Texture2DMS || + Token->Type == TokenType::Texture2DMSArray || + Token->Type == TokenType::RWTexture1D || + Token->Type == TokenType::RWTexture1DArray || + Token->Type == TokenType::RWTexture2D || + Token->Type == TokenType::RWTexture2DArray || + Token->Type == TokenType::RWTexture3D ) + { + // Process texture declaration, and add it to the top of the + // object stack + ProcessTextureDeclaration( Token, Samplers, m_Objects.back() ); + } + else + ++Token; + } + } + + ProcessShaderDeclaration( EntryPoint, ShaderType ); + + RemoveSemantics(); + + RemoveSpecialShaderAttributes(); + + GLSLSource = BuildGLSLSource(); + + return GLSLSource; +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/ProgramPipelineCache.cpp b/Graphics/GraphicsEngineOpenGL/src/ProgramPipelineCache.cpp new file mode 100644 index 00000000..4d5b3902 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/ProgramPipelineCache.cpp @@ -0,0 +1,164 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "ProgramPipelineCache.h" +#include "ShaderGLImpl.h" +#include "RenderDeviceGLImpl.h" + +namespace Diligent +{ + +ProgramPipelineCache::ProgramPipelineCache( RenderDeviceGLImpl *pRenderDeviceOpenGL ) +{ + auto &DeviceCaps = pRenderDeviceOpenGL->GetDeviceCaps(); + VERIFY( DeviceCaps.DevType != DeviceType::Undefined, "Device caps are not initialized" ); + m_bIsProgramPipelineSupported = DeviceCaps.bSeparableProgramSupported; + + m_Cache.max_load_factor(0.5f); + m_ShaderToKey.max_load_factor(0.5f); +} + +ProgramPipelineCache::~ProgramPipelineCache() +{ + VERIFY( m_Cache.empty(), "Program pipeline cache is not empty" ); + VERIFY( m_ShaderToKey.empty(), "Not all shaders that use the program pipleine are released" ); +} + +ProgramPipelineCache::CacheElementType &ProgramPipelineCache::GetProgramPipeline( RefCntAutoPtr<IShader> *ppShaders, Uint32 NumShadersToSet ) +{ + ThreadingTools::LockHelper LockHelper(m_CacheLockFlag); + + PipelineCacheKey Key = {0}; + // Create a key for the look-up + for(Uint32 Shader = 0; Shader < NumShadersToSet; ++Shader) + { + auto *pCurrShader = static_cast<IShader*>(ppShaders[Shader].RawPtr()); + switch(pCurrShader->GetDesc().ShaderType) + { + case SHADER_TYPE_VERTEX: Key.pVS = pCurrShader; break; + case SHADER_TYPE_PIXEL: Key.pPS = pCurrShader; break; + case SHADER_TYPE_GEOMETRY:Key.pGS = pCurrShader; break; + case SHADER_TYPE_HULL: Key.pHS = pCurrShader; break; + case SHADER_TYPE_DOMAIN: Key.pDS = pCurrShader; break; + case SHADER_TYPE_COMPUTE: Key.pCS = pCurrShader; break; + default: UNEXPECTED( "Unknown shader type" ); + } + } + + // Try to find the Pipeline in the map + auto It = m_Cache.find(Key); + if( It != m_Cache.end() ) + { + return It->second; + } + else + { + CacheElementType NewPipelineOrProg; + + if( m_bIsProgramPipelineSupported ) + { + // Create new progam pipeline + NewPipelineOrProg.Pipeline.Create(); + for( Uint32 Shader = 0; Shader < NumShadersToSet; ++Shader ) + { + auto *pCurrShader = static_cast<ShaderGLImpl*>(ppShaders[Shader].RawPtr()); + auto GLShaderBit = ShaderTypeToGLShaderBit( pCurrShader->GetDesc().ShaderType ); + // If the program has an active code for each stage mentioned in set flags, + // then that code will be used by the pipeline. If program is 0, then the given + // stages are cleared from the pipeline. + glUseProgramStages( NewPipelineOrProg.Pipeline, GLShaderBit, pCurrShader->m_GlProgObj ); + CHECK_GL_ERROR( "glUseProgramStages() failed" ); + } + } + else + { + // Create new progam + NewPipelineOrProg.Program.Create(); + GLuint GLProgram = NewPipelineOrProg.Program; + for( Uint32 Shader = 0; Shader < NumShadersToSet; ++Shader ) + { + auto *pCurrShader = static_cast<ShaderGLImpl*>(ppShaders[Shader].RawPtr()); + glAttachShader( GLProgram, pCurrShader->m_GLShaderObj ); + CHECK_GL_ERROR( "glAttachShader() failed" ); + } + glLinkProgram( GLProgram ); + CHECK_GL_ERROR( "glLinkProgram() failed" ); + int IsLinked = GL_FALSE; + glGetProgramiv( GLProgram, GL_LINK_STATUS, (int *)&IsLinked ); + CHECK_GL_ERROR( "glGetProgramiv() failed" ); + if( !IsLinked ) + { + int LengthWithNull = 0, Length = 0; + // Notice that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. + // The length of the info log includes a null terminator. + glGetProgramiv( GLProgram, GL_INFO_LOG_LENGTH, &LengthWithNull ); + + // The maxLength includes the NULL character + std::vector<char> shaderProgramInfoLog( LengthWithNull ); + + // Notice that glGetProgramInfoLog is used, not glGetShaderInfoLog. + glGetProgramInfoLog( GLProgram, LengthWithNull, &Length, &shaderProgramInfoLog[0] ); + VERIFY( Length == LengthWithNull-1, "Incorrect program info log len" ); + LOG_ERROR_MESSAGE( "Failed to link shader program:\n", &shaderProgramInfoLog[0], '\n'); + UNEXPECTED( "glLinkProgram failed" ); + } + + // Detach shaders from the program object + for( Uint32 Shader = 0; Shader < NumShadersToSet; ++Shader ) + { + auto *pCurrShader = static_cast<ShaderGLImpl*>(ppShaders[Shader].RawPtr()); + glDetachShader( GLProgram, pCurrShader->m_GLShaderObj ); + CHECK_GL_ERROR( "glDetachShader() failed" ); + } + + NewPipelineOrProg.Program.LoadUniforms(); + } + + auto NewElems = m_Cache.emplace( make_pair( Key, std::move( NewPipelineOrProg ) ) ); + // New element must be actually inserted + VERIFY( NewElems.second, "Element was not inserted into the hash" ); + if( Key.pVS )m_ShaderToKey.insert( make_pair(Key.pVS, Key) ); + if( Key.pGS )m_ShaderToKey.insert( make_pair(Key.pGS, Key) ); + if( Key.pPS )m_ShaderToKey.insert( make_pair(Key.pPS, Key) ); + if( Key.pDS )m_ShaderToKey.insert( make_pair(Key.pDS, Key) ); + if( Key.pHS )m_ShaderToKey.insert( make_pair(Key.pHS, Key) ); + if( Key.pCS )m_ShaderToKey.insert( make_pair(Key.pCS, Key) ); + + return NewElems.first->second; + } +} + +void ProgramPipelineCache::OnDestroyShader(IShader *pShader) +{ + ThreadingTools::LockHelper LockHelper(m_CacheLockFlag); + auto EqualRange = m_ShaderToKey.equal_range(pShader); + for(auto It = EqualRange.first; It != EqualRange.second; ++It) + { + m_Cache.erase(It->second); + } + m_ShaderToKey.erase(EqualRange.first, EqualRange.second); +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/RasterizerStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RasterizerStateGLImpl.cpp new file mode 100644 index 00000000..191253f5 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/RasterizerStateGLImpl.cpp @@ -0,0 +1,43 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "RasterizerStateGLImpl.h" +#include "RenderDeviceGLImpl.h" + +namespace Diligent +{ + +RasterizerStateGLImpl::RasterizerStateGLImpl(class IRenderDevice *pDeviceGL, const RasterizerStateDesc& RasterizerStateDesc, bool bIsDeviceInternal) : + TRasterizerStateBase(pDeviceGL, RasterizerStateDesc, bIsDeviceInternal) +{ +} + +RasterizerStateGLImpl::~RasterizerStateGLImpl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( RasterizerStateGLImpl, IID_RasterizerStateGL, TRasterizerStateBase ) + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp new file mode 100644 index 00000000..d7efc211 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp @@ -0,0 +1,110 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "RenderDeviceFactoryOpenGL.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "SwapChainGLImpl.h" + +#ifdef PLATFORM_ANDROID + #include "RenderDeviceGLESImpl.h" +#endif + +using namespace Diligent; +using namespace Diligent; + +extern "C" +{ + +#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_WINDOWS_STORE) + typedef RenderDeviceGLImpl TRenderDeviceGLImpl; +#elif defined(PLATFORM_ANDROID) + typedef RenderDeviceGLESImpl TRenderDeviceGLImpl; +#endif + +API_QUALIFIER +void CreateDeviceAndSwapChainGL( const EngineCreationAttribs& CreationAttribs, + IRenderDevice **ppDevice, + IDeviceContext **ppImmediateContext, + const SwapChainDesc& SwapChainDesc, + void *pNativeWndHandle, + Diligent::ISwapChain **ppSwapChain ) +{ + VERIFY( ppDevice && ppImmediateContext && ppSwapChain, "Null pointer is provided" ); + if( !ppDevice || !ppImmediateContext || !ppSwapChain ) + return; + + *ppDevice = nullptr; + *ppImmediateContext = nullptr; + *ppSwapChain = nullptr; + + try + { + ContextInitInfo InitInfo; + InitInfo.pNativeWndHandle = pNativeWndHandle; + InitInfo.SwapChainAttribs = SwapChainDesc; + RenderDeviceGLImpl *pRenderDeviceOpenGL( new TRenderDeviceGLImpl( InitInfo ) ); + pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); + + DeviceContextGLImpl *pDeviceContextOpenGL( new DeviceContextGLImpl( pRenderDeviceOpenGL ) ); + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceOpenGL will + // keep a weak reference to the context + pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext) ); + pRenderDeviceOpenGL->SetImmediateContext(pDeviceContextOpenGL); + + SwapChainGLImpl *pSwapChainGL = new SwapChainGLImpl(SwapChainDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); + pSwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); + + pDeviceContextOpenGL->SetSwapChain(pSwapChainGL); + // Bind default framebuffer and viewport + pDeviceContextOpenGL->SetRenderTargets( 0, nullptr, nullptr ); + pDeviceContextOpenGL->SetViewports( 1, nullptr, 0, 0 ); + + pDeviceContextOpenGL->CreateDefaultStates(); + } + catch( const std::runtime_error & ) + { + if( *ppDevice ) + { + (*ppDevice)->Release(); + *ppDevice = nullptr; + } + + if( *ppImmediateContext ) + { + (*ppImmediateContext)->Release(); + *ppImmediateContext = nullptr; + } + + if( *ppSwapChain ) + { + (*ppSwapChain)->Release(); + *ppSwapChain = nullptr; + } + + LOG_ERROR( "Failed to initialize OpenGL-based render device" ); + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp new file mode 100644 index 00000000..932cd4d6 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp @@ -0,0 +1,51 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "RenderDeviceGLESImpl.h" + +namespace Diligent +{ + RenderDeviceGLESImpl::RenderDeviceGLESImpl( const ContextInitInfo &InitInfo ) : + RenderDeviceGLImpl( InitInfo ) + { + } + + IMPLEMENT_QUERY_INTERFACE( RenderDeviceGLESImpl, IID_RenderDeviceGLES, RenderDeviceGLImpl ) + + bool RenderDeviceGLESImpl::Invalidate() + { + return m_GLContext.Invalidate(); + } + + void RenderDeviceGLESImpl::Suspend() + { + m_GLContext.Suspend(); + } + + EGLint RenderDeviceGLESImpl::Resume( ANativeWindow* window ) + { + return m_GLContext.Resume(window); + } +} diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp new file mode 100644 index 00000000..fafa7f51 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -0,0 +1,631 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "RenderDeviceGLImpl.h" + +#include "BufferGLImpl.h" +#include "VertexDescGLImpl.h" +#include "ShaderGLImpl.h" +#include "VAOCache.h" +#include "ProgramPipelineCache.h" +#include "Texture1D_OGL.h" +#include "Texture1DArray_OGL.h" +#include "Texture2D_OGL.h" +#include "Texture2DArray_OGL.h" +#include "Texture3D_OGL.h" +#include "SamplerGLImpl.h" +#include "DSStateGLImpl.h" +#include "RasterizerStateGLImpl.h" +#include "BlendStateGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "GLTypeConversions.h" + +namespace Diligent +{ + +RenderDeviceGLImpl :: RenderDeviceGLImpl(const ContextInitInfo &InitInfo): + // Device caps must be filled in before the constructor of Pipeline Cache is called! + m_GLContext(InitInfo, m_DeviceCaps), + m_PipelineCache(this), + m_EmptyVAO(true), + m_TexRegionRender(this) +{ + GLint NumExtensions = 0; + glGetIntegerv( GL_NUM_EXTENSIONS, &NumExtensions ); + CHECK_GL_ERROR( "Failed to get the number of extensions" ); + m_ExtensionStrings.reserve(NumExtensions); + for( int Ext = 0; Ext < NumExtensions; ++Ext ) + { + auto CurrExtension = glGetStringi( GL_EXTENSIONS, Ext ); + CHECK_GL_ERROR( "Failed to get extension string #", Ext ); + m_ExtensionStrings.emplace( reinterpret_cast<const Char*>(CurrExtension) ); + } + + FlagSupportedTexFormats(); + QueryDeviceCaps(); + + std::basic_string<GLubyte> glstrVendor = glGetString( GL_VENDOR ); + std::string Vendor(glstrVendor.begin(), glstrVendor.end()); + transform(Vendor.begin(), Vendor.end(), Vendor.begin(), ::tolower); + if( Vendor.find( "intel" ) != string::npos ) + m_GPUInfo.Vendor = GPU_VENDOR::INTEL; + else if( Vendor.find( "nvidia" ) != string::npos ) + m_GPUInfo.Vendor = GPU_VENDOR::NVIDIA; + else if( Vendor.find( "ati" ) != string::npos || + Vendor.find( "amd" ) != string::npos ) + m_GPUInfo.Vendor = GPU_VENDOR::ATI; +} + +RenderDeviceGLImpl :: ~RenderDeviceGLImpl() +{ +} + +IMPLEMENT_QUERY_INTERFACE( RenderDeviceGLImpl, IID_GLDeviceBaseInterface, TRenderDeviceBase ) + +void RenderDeviceGLImpl :: CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer, bool bIsDeviceInternal) +{ + CreateDeviceObject( "buffer", BuffDesc, ppBuffer, + [&]() + { + BufferGLImpl *pBufferOGL( new BufferGLImpl( this, BuffDesc, BuffData, bIsDeviceInternal ) ); + pBufferOGL->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); + pBufferOGL->CreateDefaultViews(); + OnCreateDeviceObject( pBufferOGL ); + } + ); +} + +void RenderDeviceGLImpl :: CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer) +{ + CreateBuffer(BuffDesc, BuffData, ppBuffer, false); +} + +void RenderDeviceGLImpl::CreateVertexDescription( const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc, bool bIsDeviceInternal ) +{ + CreateDeviceObject( "vertex description", LayoutDesc, ppVertexDesc, + [&]() + { + VertexDescGLImpl *pDescOGL( new VertexDescGLImpl( this, LayoutDesc, bIsDeviceInternal ) ); + pDescOGL->QueryInterface(IID_VertexDescription, reinterpret_cast<IObject**>(ppVertexDesc) ); + + OnCreateDeviceObject( pDescOGL ); + } + ); +} +void RenderDeviceGLImpl::CreateVertexDescription(const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc) +{ + CreateVertexDescription(LayoutDesc, pVertexShader, ppVertexDesc, false); +} + + +void RenderDeviceGLImpl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader, bool bIsDeviceInternal) +{ + CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, + [&]() + { + ShaderGLImpl *pShaderOGL(new ShaderGLImpl(this, ShaderCreationAttribs, bIsDeviceInternal)); + pShaderOGL->QueryInterface(IID_Shader, reinterpret_cast<IObject**>(ppShader) ); + + OnCreateDeviceObject( pShaderOGL ); + } + ); +} + +void RenderDeviceGLImpl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader) +{ + CreateShader(ShaderCreationAttribs, ppShader, false); +} + +void RenderDeviceGLImpl :: CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture, bool bIsDeviceInternal) +{ + CreateDeviceObject( "texture", TexDesc, ppTexture, + [&]() + { + auto spDeviceContext = GetImmediateContext(); + VERIFY(spDeviceContext, "Immediate device context has been destroyed"); + auto pDeviceContext = ValidatedCast<DeviceContextGLImpl>( spDeviceContext.RawPtr() ); + const auto &FmtInfo = GetTextureFormatInfo( TexDesc.Format ); + if( !FmtInfo.Supported ) + { + LOG_ERROR_AND_THROW( FmtInfo.Name, " is not supported texture format" ); + } + + TextureBaseGL *pTextureOGL = nullptr; + switch(TexDesc.Type) + { + case TEXTURE_TYPE_1D: + pTextureOGL = new Texture1D_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + break; + + case TEXTURE_TYPE_1D_ARRAY: + pTextureOGL = new Texture1DArray_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + break; + + case TEXTURE_TYPE_2D: + pTextureOGL = new Texture2D_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + break; + + case TEXTURE_TYPE_2D_ARRAY: + pTextureOGL = new Texture2DArray_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + break; + + case TEXTURE_TYPE_3D: + pTextureOGL = new Texture3D_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + break; + + default: LOG_ERROR_AND_THROW( "Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)" ); + } + + pTextureOGL->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); + pTextureOGL->CreateDefaultViews(); + OnCreateDeviceObject( pTextureOGL ); + } + ); +} + +void RenderDeviceGLImpl::CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture) +{ + CreateTexture(TexDesc, Data, ppTexture, false); +} + +void RenderDeviceGLImpl :: CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler, bool bIsDeviceInternal) +{ + CreateDeviceObject( "sampler", SamplerDesc, ppSampler, + [&]() + { + m_SamplersRegistry.Find( SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler) ); + if( *ppSampler == nullptr ) + { + SamplerGLImpl *pSamplerOGL( new SamplerGLImpl( this, SamplerDesc, bIsDeviceInternal ) ); + pSamplerOGL->QueryInterface( IID_Sampler, reinterpret_cast<IObject**>(ppSampler) ); + OnCreateDeviceObject( pSamplerOGL ); + m_SamplersRegistry.Add( SamplerDesc, *ppSampler ); + } + } + ); +} + +void RenderDeviceGLImpl::CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler) +{ + CreateSampler(SamplerDesc, ppSampler, false); +} + +void RenderDeviceGLImpl::CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState, bool bIsDeviceInternal ) +{ + CreateDeviceObject( "depth-stencil state", DSSDesc, ppDepthStencilState, + [&]() + { + m_DSSRegistry.Find( DSSDesc, reinterpret_cast<IDeviceObject**>(ppDepthStencilState) ); + if( *ppDepthStencilState == nullptr ) + { + DSStateGLImpl *pDSSOGL( new DSStateGLImpl( this, DSSDesc, bIsDeviceInternal ) ); + pDSSOGL->QueryInterface( IID_DepthStencilState, reinterpret_cast<IObject**>(ppDepthStencilState) ); + OnCreateDeviceObject( pDSSOGL ); + m_DSSRegistry.Add( DSSDesc, pDSSOGL ); + } + } + ); +} + +void RenderDeviceGLImpl::CreateDepthStencilState(const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState) +{ + CreateDepthStencilState( DSSDesc, ppDepthStencilState, false ); +} + +void RenderDeviceGLImpl::CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState, bool bIsDeviceInternal ) +{ + CreateDeviceObject( "rasterizer state", RSDesc, ppRasterizerState, + [&]() + { + m_RSRegistry.Find( RSDesc, reinterpret_cast<IDeviceObject**>(ppRasterizerState) ); + if( *ppRasterizerState == nullptr ) + { + RasterizerStateGLImpl *pRSOGL( new RasterizerStateGLImpl( this, RSDesc, bIsDeviceInternal ) ); + pRSOGL->QueryInterface( IID_RasterizerState, reinterpret_cast<IObject**>(ppRasterizerState) ); + OnCreateDeviceObject( pRSOGL ); + m_RSRegistry.Add( RSDesc, pRSOGL ); + } + } + ); +} +void RenderDeviceGLImpl::CreateRasterizerState(const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState) +{ + CreateRasterizerState( RSDesc, ppRasterizerState, false ); +} + +void RenderDeviceGLImpl::CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState, bool bIsDeviceInternal ) +{ + CreateDeviceObject( "blend state", BSDesc, ppBlendState, + [&]() + { + m_BSRegistry.Find( BSDesc, reinterpret_cast<IDeviceObject**>(ppBlendState) ); + if( *ppBlendState == nullptr ) + { + BlendStateGLImpl *pBSOGL( new BlendStateGLImpl( this, BSDesc, bIsDeviceInternal ) ); + pBSOGL->QueryInterface( IID_BlendState, reinterpret_cast<IObject**>(ppBlendState) ); + OnCreateDeviceObject( pBSOGL ); + m_BSRegistry.Add( BSDesc, pBSOGL ); + } + } + ); +} +void RenderDeviceGLImpl::CreateBlendState(const BlendStateDesc &BSDesc, IBlendState **ppBlendState) +{ + CreateBlendState( BSDesc, ppBlendState, false ); +} + +bool RenderDeviceGLImpl::CheckExtension( const Char *ExtensionString ) +{ + return m_ExtensionStrings.find( ExtensionString ) != m_ExtensionStrings.end(); +} + +void RenderDeviceGLImpl::FlagSupportedTexFormats() +{ + const auto &DeviceCaps = GetDeviceCaps(); + bool bGL33OrAbove = DeviceCaps.DevType == DeviceType::OpenGL && + (DeviceCaps.MajorVersion >= 4 || DeviceCaps.MajorVersion == 3 && DeviceCaps.MinorVersion >= 3); + + bool bRGTC = CheckExtension( "GL_ARB_texture_compression_rgtc" ); + bool bBPTC = CheckExtension( "GL_ARB_texture_compression_bptc" ); + bool bS3TC = CheckExtension( "GL_EXT_texture_compression_s3tc" ); + bool bTexNorm16 = CheckExtension( "GL_EXT_texture_norm16" ); // Only for ES3.1+ + +#define FLAG_FORMAT(Fmt, IsSupported)\ + m_TextureFormatsInfo[Fmt].Supported=IsSupported + + // The formats marked by true below are required in GL 3.3+ and GLES 3.0+ + // Note that GLES2.0 does not specify any required formats + + FLAG_FORMAT(TEX_FORMAT_RGBA32_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA32_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA32_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA32_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_RGB32_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_RGB32_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_RGB32_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_RGB32_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA16_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA16_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA16_UNORM, bGL33OrAbove || bTexNorm16 ); + FLAG_FORMAT(TEX_FORMAT_RGBA16_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA16_SNORM, bGL33OrAbove || bTexNorm16 ); + FLAG_FORMAT(TEX_FORMAT_RGBA16_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_RG32_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_RG32_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_RG32_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_RG32_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_R32G8X24_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_D32_FLOAT_S8X24_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_X32_TYPELESS_G8X24_UINT, false ); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_UNORM, true ); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_R11G11B10_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA8_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM_SRGB, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA8_SNORM, true ); + FLAG_FORMAT(TEX_FORMAT_RGBA8_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_RG16_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_RG16_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_RG16_UNORM, bGL33OrAbove || bTexNorm16 ); + FLAG_FORMAT(TEX_FORMAT_RG16_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_RG16_SNORM, bGL33OrAbove || bTexNorm16 ); + FLAG_FORMAT(TEX_FORMAT_RG16_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_R32_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_D32_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_R32_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_R32_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_R32_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_R24G8_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_D24_UNORM_S8_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_R24_UNORM_X8_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_X24_TYPELESS_G8_UINT, false ); + FLAG_FORMAT(TEX_FORMAT_RG8_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_RG8_UNORM, true ); + FLAG_FORMAT(TEX_FORMAT_RG8_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_RG8_SNORM, true ); + FLAG_FORMAT(TEX_FORMAT_RG8_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_R16_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_R16_FLOAT, true ); + FLAG_FORMAT(TEX_FORMAT_D16_UNORM, true ); + FLAG_FORMAT(TEX_FORMAT_R16_UNORM, bGL33OrAbove || bTexNorm16 ); + FLAG_FORMAT(TEX_FORMAT_R16_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_R16_SNORM, bGL33OrAbove || bTexNorm16 ); + FLAG_FORMAT(TEX_FORMAT_R16_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_R8_TYPELESS, true ); + FLAG_FORMAT(TEX_FORMAT_R8_UNORM, true ); + FLAG_FORMAT(TEX_FORMAT_R8_UINT, true ); + FLAG_FORMAT(TEX_FORMAT_R8_SNORM, true ); + FLAG_FORMAT(TEX_FORMAT_R8_SINT, true ); + FLAG_FORMAT(TEX_FORMAT_A8_UNORM, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_R1_UNORM, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_RGB9E5_SHAREDEXP, true ); + FLAG_FORMAT(TEX_FORMAT_RG8_B8G8_UNORM, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_G8R8_G8B8_UNORM, false ); // Not supported in OpenGL + + FLAG_FORMAT(TEX_FORMAT_BC1_TYPELESS, bS3TC ); + FLAG_FORMAT(TEX_FORMAT_BC1_UNORM, bS3TC ); + FLAG_FORMAT(TEX_FORMAT_BC1_UNORM_SRGB, bS3TC ); + FLAG_FORMAT(TEX_FORMAT_BC2_TYPELESS, bS3TC ); + FLAG_FORMAT(TEX_FORMAT_BC2_UNORM, bS3TC ); + FLAG_FORMAT(TEX_FORMAT_BC2_UNORM_SRGB, bS3TC ); + FLAG_FORMAT(TEX_FORMAT_BC3_TYPELESS, bS3TC ); + FLAG_FORMAT(TEX_FORMAT_BC3_UNORM, bS3TC ); + FLAG_FORMAT(TEX_FORMAT_BC3_UNORM_SRGB, bS3TC ); + + FLAG_FORMAT(TEX_FORMAT_BC4_TYPELESS, bRGTC ); + FLAG_FORMAT(TEX_FORMAT_BC4_UNORM, bRGTC ); + FLAG_FORMAT(TEX_FORMAT_BC4_SNORM, bRGTC ); + FLAG_FORMAT(TEX_FORMAT_BC5_TYPELESS, bRGTC ); + FLAG_FORMAT(TEX_FORMAT_BC5_UNORM, bRGTC ); + FLAG_FORMAT(TEX_FORMAT_BC5_SNORM, bRGTC ); + + FLAG_FORMAT(TEX_FORMAT_B5G6R5_UNORM, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_B5G5R5A1_UNORM, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_BGRA8_TYPELESS, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM_SRGB, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_BGRX8_TYPELESS, false ); // Not supported in OpenGL + FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM_SRGB, false ); // Not supported in OpenGL + + FLAG_FORMAT(TEX_FORMAT_BC6H_TYPELESS, bBPTC ); + FLAG_FORMAT(TEX_FORMAT_BC6H_UF16, bBPTC ); + FLAG_FORMAT(TEX_FORMAT_BC6H_SF16, bBPTC ); + FLAG_FORMAT(TEX_FORMAT_BC7_TYPELESS, bBPTC ); + FLAG_FORMAT(TEX_FORMAT_BC7_UNORM, bBPTC ); + FLAG_FORMAT(TEX_FORMAT_BC7_UNORM_SRGB, bBPTC ); + +#ifdef _DEBUG + bool bGL43OrAbove = DeviceCaps.DevType == DeviceType::OpenGL && + (DeviceCaps.MajorVersion >= 5 || DeviceCaps.MajorVersion == 4 && DeviceCaps.MinorVersion >= 3); + + const int TestTextureDim = 32; + const int MaxTexelSize = 16; + std::vector<Uint8> ZeroData(TestTextureDim * TestTextureDim * MaxTexelSize); + + // Go through all formats and try to create small 2D texture to check if the format is supported + for( auto FmtInfo = m_TextureFormatsInfo.begin(); FmtInfo != m_TextureFormatsInfo.end(); ++FmtInfo ) + { + if( FmtInfo->Format == TEX_FORMAT_UNKNOWN ) + continue; + + auto GLFmt = TexFormatToGLInternalTexFormat(FmtInfo->Format); + if( GLFmt == 0 ) + { + VERIFY( !FmtInfo->Supported, "Format should be marked as unsupported" ); + continue; + } + + // Only works on GL4.3+ + if( bGL43OrAbove ) + { + GLint params = 0; + glGetInternalformativ( GL_TEXTURE_2D, GLFmt, GL_INTERNALFORMAT_SUPPORTED, 1, ¶ms ); + CHECK_GL_ERROR( "glGetInternalformativ() failed" ); + VERIFY( FmtInfo->Supported == (params == GL_TRUE), "This internal format should be supported" ); + } + + // Check that the format is indeed supported + if( FmtInfo->Supported ) + { + GLObjectWrappers::GLTextureObj TestGLTex( true ); + // Immediate context is not created yet, so use raw GL functions + glBindTexture( GL_TEXTURE_2D, TestGLTex ); + CHECK_GL_ERROR( "Failed to bind texture" ); + glTexStorage2D( GL_TEXTURE_2D, 1, GLFmt, TestTextureDim, TestTextureDim ); + CHECK_GL_ERROR( "Failed to allocate storage for the test texture. Test format: ", FmtInfo->Name); + + // It turned out it is not enough to only allocate texture storage + // For some reason glTexStorage2D() may succeed, but upload operation + // will later fail. So we need to additionally try to upload some + // data to the texture + auto TransferAttribs = GetNativePixelTransferAttribs( FmtInfo->Format ); + if( FmtInfo->ComponentType != COMPONENT_TYPE_COMPRESSED ) + { + glTexSubImage2D( GL_TEXTURE_2D, 0, // mip level + 0, 0, TestTextureDim, TestTextureDim, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + ZeroData.data() ); + } + CHECK_GL_ERROR( "Failed to upload data to the test texture. Test format: ", FmtInfo->Name); + glBindTexture( GL_TEXTURE_2D, 0 ); + } + } +#endif +} + +template<typename CreateFuncType> +bool CreateTestGLTexture(GLContextState &GlCtxState, GLenum BindTarget, const GLObjectWrappers::GLTextureObj &GLTexObj, CreateFuncType CreateFunc) +{ + GlCtxState.BindTexture(-1, BindTarget, GLTexObj); + CreateFunc(); + bool bSuccess = glGetError() == GL_NO_ERROR; + GlCtxState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj(false) ); + return bSuccess; +} + +void RenderDeviceGLImpl::TestTextureFormat( TEXTURE_FORMAT TexFormat ) +{ + auto &TexFormatInfo = m_TextureFormatsInfo[TexFormat]; + VERIFY( TexFormatInfo.Supported, "Texture format is not supported" ); + + auto GLFmt = TexFormatToGLInternalTexFormat(TexFormat); + VERIFY( GLFmt != 0, "Incorrect internal GL format" ); + + auto spDeviceContext = GetImmediateContext(); + VERIFY(spDeviceContext, "Immediate device context has been destroyed"); + auto *pContextGL = ValidatedCast<DeviceContextGLImpl>( spDeviceContext.RawPtr() ); + auto &ContextState = pContextGL->GetContextState(); + + const int TestTextureDim = 32; + const int TestTextureDepth = 8; + + // Create test texture 1D + TexFormatInfo.Tex1DFmt = false; + if( m_DeviceCaps.TexCaps.bTexture1DSupported && + TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED ) + { + GLObjectWrappers::GLTextureObj TestGLTex( true ); + TexFormatInfo.Tex1DFmt = CreateTestGLTexture( ContextState, GL_TEXTURE_1D, TestGLTex, [&]() + { + glTexStorage1D(GL_TEXTURE_1D, 1, GLFmt, TestTextureDim); + } ); + } + + // Create test texture 2D + TexFormatInfo.Tex2DFmt = false; + TexFormatInfo.TexCubeFmt = false; + TexFormatInfo.ColorRenderable = false; + TexFormatInfo.DepthRenderable = false; + { + GLObjectWrappers::GLTextureObj TestGLTex( true ); + TexFormatInfo.Tex2DFmt = CreateTestGLTexture( ContextState, GL_TEXTURE_2D, TestGLTex, [&]() + { + glTexStorage2D(GL_TEXTURE_2D, 1, GLFmt, TestTextureDim, TestTextureDim); + } ); + + if( TexFormatInfo.Tex2DFmt ) + { + { + GLObjectWrappers::GLTextureObj TestGLCubeTex( true ); + TexFormatInfo.TexCubeFmt = CreateTestGLTexture( ContextState, GL_TEXTURE_CUBE_MAP, TestGLCubeTex, [&]() + { + glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GLFmt, TestTextureDim, TestTextureDim); + } ); + } + + bool bTestDepthAttachment = + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL; + bool bTestColorAttachment = !bTestDepthAttachment && TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED; + + GLObjectWrappers::GLFrameBufferObj NewFBO(false); + + GLint CurrentFramebuffer = -1; + if( bTestColorAttachment || bTestDepthAttachment ) + { + glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &CurrentFramebuffer ); + CHECK_GL_ERROR( "Failed to get current framebuffer"); + + NewFBO.Create(); + glBindFramebuffer( GL_DRAW_FRAMEBUFFER, NewFBO ); + CHECK_GL_ERROR( "Failed to bind the framebuffer"); + } + + if( bTestDepthAttachment ) + { + GLenum Attachment = TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT; + glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, Attachment, GL_TEXTURE_2D, TestGLTex, 0 ); + if( glGetError() == GL_NO_ERROR ) + { + // Create dummy texture2D since some older version do not allow depth only + // attachments + GLObjectWrappers::GLTextureObj ColorTex( true ); + bool Success = CreateTestGLTexture( ContextState, GL_TEXTURE_2D, ColorTex, [&]() + { + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, TestTextureDim, TestTextureDim); + } ); + VERIFY( Success, "Failed to create dummy render target texture" ); + glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorTex, 0 ); + CHECK_GL_ERROR( "Failed to set bind dummy render target to framebuffer" ); + + static const GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers( _countof( DrawBuffers ), DrawBuffers ); + CHECK_GL_ERROR( "Failed to set draw buffers via glDrawBuffers()" ); + + GLenum Status = glCheckFramebufferStatus( GL_FRAMEBUFFER ); + TexFormatInfo.DepthRenderable = (glGetError() == GL_NO_ERROR) && (Status == GL_FRAMEBUFFER_COMPLETE); + } + } + else if( bTestColorAttachment ) + { + glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, TestGLTex, 0 ); + if( glGetError() == GL_NO_ERROR ) + { + static const GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers( _countof( DrawBuffers ), DrawBuffers ); + CHECK_GL_ERROR( "Failed to set draw buffers via glDrawBuffers()" ); + + GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + TexFormatInfo.ColorRenderable = (glGetError() == GL_NO_ERROR) && (Status == GL_FRAMEBUFFER_COMPLETE); + } + } + + if( bTestColorAttachment || bTestDepthAttachment ) + { + glBindFramebuffer( GL_DRAW_FRAMEBUFFER, CurrentFramebuffer ); + CHECK_GL_ERROR( "Failed to bind the framebuffer"); + } + } + } + + TexFormatInfo.SupportsMS = false; + if( TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED && + m_DeviceCaps.TexCaps.bTexture2DMSSupported ) + { + GLObjectWrappers::GLTextureObj TestGLTex( true ); + TexFormatInfo.SupportsMS = CreateTestGLTexture( ContextState, GL_TEXTURE_2D_MULTISAMPLE, TestGLTex, [&]() + { + glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GLFmt, TestTextureDim, TestTextureDim, GL_TRUE); + } ); + } + + // Create test texture 3D + TexFormatInfo.Tex3DFmt = false; + // 3D textures do not support depth formats + if( !(TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL) ) + { + GLObjectWrappers::GLTextureObj TestGLTex( true ); + TexFormatInfo.Tex3DFmt = CreateTestGLTexture( ContextState, GL_TEXTURE_3D, TestGLTex, [&]() + { + glTexStorage3D(GL_TEXTURE_3D, 1, GLFmt, TestTextureDim, TestTextureDim, TestTextureDepth); + } ); + } +} + +void RenderDeviceGLImpl :: QueryDeviceCaps() +{ + { + // Test glPolygonMode() function to check if it fails + // (It does fail on NVidia Shield tablet, but works fine + // on Intel hw) + VERIFY( glGetError() == GL_NO_ERROR, "Unhandled gl error encountered" ); + m_DeviceCaps.bWireframeFillSupported = True; + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + if( glGetError() != GL_NO_ERROR ) + m_DeviceCaps.bWireframeFillSupported = False; + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + if( glGetError() != GL_NO_ERROR ) + m_DeviceCaps.bWireframeFillSupported = False; + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp new file mode 100644 index 00000000..c26a6a80 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp @@ -0,0 +1,124 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "SamplerGLImpl.h" +#include "RenderDeviceGLImpl.h" +#include "GLTypeConversions.h" + +namespace Diligent +{ + +SamplerGLImpl::SamplerGLImpl(class RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal) : + TSamplerBase( pDeviceGL, SamplerDesc, bIsDeviceInternal ), + m_GlSampler(true) +{ + const auto& SamCaps = pDeviceGL->GetDeviceCaps().SamCaps; + + Bool bMinAnisotropic = False, bMagAnisotropic = False, bMipAnisotropic = False; + Bool bMinComparison = False, bMagComparison = False, bMipComparison = False; + GLenum GLMinFilter, GLMagFilter, GLMipFilter; + FilterTypeToGLFilterType(SamplerDesc.MinFilter, GLMinFilter, bMinAnisotropic, bMinComparison); + FilterTypeToGLFilterType(SamplerDesc.MagFilter, GLMagFilter, bMagAnisotropic, bMagComparison); + FilterTypeToGLFilterType(SamplerDesc.MipFilter, GLMipFilter, bMipAnisotropic, bMipComparison); + VERIFY( bMinAnisotropic == bMagAnisotropic && bMagAnisotropic == bMipAnisotropic, "Incosistent anisotropy filter setting" ); + VERIFY( bMinComparison == bMagComparison && bMagComparison == bMipComparison, "Incosistent comparison filter setting" ); + + glSamplerParameteri(m_GlSampler, GL_TEXTURE_MAG_FILTER, GLMagFilter); + + GLenum GlMinMipFilter = 0; + if( GLMinFilter == GL_NEAREST && GLMipFilter == GL_NEAREST ) + GlMinMipFilter = GL_NEAREST_MIPMAP_NEAREST; + else if( GLMinFilter == GL_LINEAR && GLMipFilter == GL_NEAREST ) + GlMinMipFilter = GL_LINEAR_MIPMAP_NEAREST; + else if( GLMinFilter == GL_NEAREST && GLMipFilter == GL_LINEAR ) + GlMinMipFilter = GL_NEAREST_MIPMAP_LINEAR; + else if( GLMinFilter == GL_LINEAR && GLMipFilter == GL_LINEAR ) + GlMinMipFilter = GL_LINEAR_MIPMAP_LINEAR; + else + LOG_ERROR_AND_THROW( "Unsupported min/mip filter combination" ); + glSamplerParameteri(m_GlSampler, GL_TEXTURE_MIN_FILTER, GlMinMipFilter); + + GLenum WrapModes[3] = { 0 }; + TEXTURE_ADDRESS_MODE AddressModes[] = + { + SamplerDesc.AddressU, + SamplerDesc.AddressV, + SamplerDesc.AddressW + }; + for( int i = 0; i < _countof( AddressModes ); ++i ) + { + auto &WrapMode = WrapModes[i]; + WrapMode = TexAddressModeToGLAddressMode( AddressModes[i] ); + if( !SamCaps.bBorderSamplingModeSupported && WrapMode == GL_CLAMP_TO_BORDER ) + { + LOG_ERROR_MESSAGE( "GL_CLAMP_TO_BORDER filtering mode is not supported. Defaulting to GL_CLAMP_TO_EDGE.\n" ); + WrapMode = GL_CLAMP_TO_EDGE; + } + } + glSamplerParameteri(m_GlSampler, GL_TEXTURE_WRAP_S, WrapModes[0]); + glSamplerParameteri(m_GlSampler, GL_TEXTURE_WRAP_T, WrapModes[1]); + glSamplerParameteri(m_GlSampler, GL_TEXTURE_WRAP_R, WrapModes[2]); + + if( SamCaps.bLODBiasSupported ) // Can be unsupported + glSamplerParameterf(m_GlSampler, GL_TEXTURE_LOD_BIAS, SamplerDesc.MipLODBias); + else + { + if( SamplerDesc.MipLODBias ) + LOG_WARNING_MESSAGE( "Texture LOD bias sampler attribute is not supported\n" ); + } + + if( SamCaps.bAnisotropicFilteringSupported ) // Can be unsupported + glSamplerParameterf(m_GlSampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, bMipAnisotropic ? static_cast<float>(SamplerDesc.MaxAnisotropy) : 1.f); + else + { + if( bMipAnisotropic && SamplerDesc.MaxAnisotropy != 1 ) + LOG_WARNING_MESSAGE( "Max anisotropy sampler attribute is not supported\n" ); + } + + glSamplerParameteri(m_GlSampler, GL_TEXTURE_COMPARE_MODE, bMinComparison ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE); + + if( SamCaps.bBorderSamplingModeSupported ) // Can be unsupported + glSamplerParameterfv(m_GlSampler, GL_TEXTURE_BORDER_COLOR, SamplerDesc.BorderColor); + else + { + if( SamplerDesc.BorderColor[0] != 0 || SamplerDesc.BorderColor[1] != 0 || SamplerDesc.BorderColor[2] != 0 || SamplerDesc.BorderColor[3] != 0 ) + LOG_WARNING_MESSAGE( "Border color sampler attribute is not supported\n" ); + } + GLenum GLCompareFunc = CompareFuncToGLCompareFunc(SamplerDesc.ComparisonFunc); + glSamplerParameteri(m_GlSampler, GL_TEXTURE_COMPARE_FUNC, GLCompareFunc); + + glSamplerParameterf(m_GlSampler, GL_TEXTURE_MAX_LOD, SamplerDesc.MaxLOD); + glSamplerParameterf(m_GlSampler, GL_TEXTURE_MIN_LOD, SamplerDesc.MinLOD); + + CHECK_GL_ERROR_AND_THROW("Failed to create OpenGL texture sampler\n"); +} + +SamplerGLImpl::~SamplerGLImpl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( SamplerGLImpl, IID_SamplerGL, TSamplerBase ) + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp new file mode 100644 index 00000000..0f650bdd --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -0,0 +1,342 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "ShaderGLImpl.h" +#include "RenderDeviceGLImpl.h" +#include "DataBlobImpl.h" +#include "HLSL2GLSLConverter.h" + +using namespace Diligent; + +namespace Diligent +{ + +static const Char* g_GLSLDefinitions = +{ + #include "GLSLDefinitions_inc.h" +}; + +ShaderGLImpl::ShaderGLImpl(RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &ShaderCreationAttribs, bool bIsDeviceInternal) : + TShaderBase( pDeviceGL, ShaderCreationAttribs.Desc, bIsDeviceInternal ), + m_GlProgObj(false), + m_GLShaderObj( false, GLObjectWrappers::GLShaderObjCreateReleaseHelper( GetGLShaderType( m_Desc.ShaderType ) ) ) +{ + std::vector<const char *> ShaderStrings; + + // Each element in the length array may contain the length of the corresponding string + // (the null character is not counted as part of the string length). + // Not specifying lengths causes shader compilation errors on Android + std::vector<GLint> Lenghts; + + ShaderStrings.push_back( +#if defined(_WINDOWS) + "#version 430 core\n" + "#define DESKTOP_GL 1\n" +#elif defined(ANDROID) + "#version 310 es\n" + + "#extension GL_EXT_shader_io_blocks : enable\n" // This is required on NVidia + + "#ifndef GL_ES\n" + "# define GL_ES 1\n" + "#endif\n" + + "precision highp float;\n" + "precision highp int;\n" + //"precision highp uint;\n" // This line causes shader compilation error on NVidia! + + "precision highp sampler2D;\n" + "precision highp sampler3D;\n" + "precision highp samplerCube;\n" + "precision highp samplerCubeArray;\n" + "precision highp samplerCubeShadow;\n" + "precision highp samplerCubeArrayShadow;\n" + "precision highp sampler2DShadow;\n" + "precision highp sampler2DArray;\n" + "precision highp sampler2DArrayShadow;\n" + "precision highp sampler2DMS;\n" // ES3.1 + + "precision highp isampler2D;\n" + "precision highp isampler3D;\n" + "precision highp isamplerCube;\n" + "precision highp isamplerCubeArray;\n" + "precision highp isampler2DArray;\n" + "precision highp isampler2DMS;\n" // ES3.1 + + "precision highp usampler2D;\n" + "precision highp usampler3D;\n" + "precision highp usamplerCube;\n" + "precision highp usamplerCubeArray;\n" + "precision highp usampler2DArray;\n" + "precision highp usampler2DMS;\n" // ES3.1 + + "precision highp image2D;\n" + "precision highp image3D;\n" + "precision highp imageCube;\n" + "precision highp image2DArray;\n" + + "precision highp iimage2D;\n" + "precision highp iimage3D;\n" + "precision highp iimageCube;\n" + "precision highp iimage2DArray;\n" + + "precision highp uimage2D;\n" + "precision highp uimage3D;\n" + "precision highp uimageCube;\n" + "precision highp uimage2DArray;\n" +#endif + // It would be much more convenient to use row_major matrices. + // But unfortunatelly on NVIDIA, the following directive + // layout(std140, row_major) uniform; + // does not have any effect on matrices that are part of structures + // So we have to use column-major matrices which are default in both + // DX and GLSL. + "layout(std140) uniform;\n" + ); + Lenghts.push_back( static_cast<GLint>( strlen( ShaderStrings.back() ) ) ); + + const Char* ShaderTypeDefine = nullptr; + switch( m_Desc.ShaderType ) + { + case SHADER_TYPE_VERTEX: ShaderTypeDefine = "#define VERTEX_SHADER\n"; break; + case SHADER_TYPE_PIXEL: ShaderTypeDefine = "#define FRAGMENT_SHADER\n"; break; + case SHADER_TYPE_GEOMETRY: ShaderTypeDefine = "#define GEOMETRY_SHADER\n"; break; + case SHADER_TYPE_HULL: ShaderTypeDefine = "#define TESS_CONTROL_SHADER\n"; break; + case SHADER_TYPE_DOMAIN: ShaderTypeDefine = "#define TESS_EVALUATION_SHADER\n";break; + case SHADER_TYPE_COMPUTE: ShaderTypeDefine = "#define COMPUTE_SHADER\n"; break; + default: UNEXPECTED("Shader type is not specified"); + } + ShaderStrings.push_back( ShaderTypeDefine ); + Lenghts.push_back( static_cast<GLint>( strlen(ShaderTypeDefine) ) ); + + String UserDefines; + if( ShaderCreationAttribs.Macros != nullptr) + { + auto *pMacro = ShaderCreationAttribs.Macros; + while( pMacro->Name != nullptr && pMacro->Definition != nullptr ) + { + UserDefines += "#define "; + UserDefines += pMacro->Name; + UserDefines += ' '; + UserDefines += pMacro->Definition; + UserDefines += "\n"; + ++pMacro; + } + ShaderStrings.push_back( UserDefines.c_str() ); + Lenghts.push_back( static_cast<GLint>( UserDefines.length() ) ); + } + + RefCntAutoPtr<Diligent::IDataBlob> pFileData(new Diligent::DataBlobImpl); + auto ShaderSource = ShaderCreationAttribs.Source; + GLuint SourceLen = 0; + if( ShaderSource ) + { + SourceLen = (GLint)strlen(ShaderSource); + } + else + { + VERIFY(ShaderCreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null"); + RefCntAutoPtr<IFileStream> pSourceStream; + ShaderCreationAttribs.pShaderSourceStreamFactory->CreateInputStream( ShaderCreationAttribs.FilePath, &pSourceStream ); + pSourceStream->Read( pFileData ); + ShaderSource = reinterpret_cast<char*>(pFileData->GetDataPtr()); + SourceLen = static_cast<GLint>( pFileData->GetSize() ); + } + + String ConvertedSource; + if( ShaderCreationAttribs.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL ) + { + ShaderStrings.push_back( g_GLSLDefinitions ); + static const auto GLSLDefinitionsLen = strlen( g_GLSLDefinitions ); + Lenghts.push_back( static_cast<GLint>( GLSLDefinitionsLen ) ); + + // Convert HLSL to GLSL + HLSL2GLSLConverter Converter(ShaderCreationAttribs.pShaderSourceStreamFactory); + ConvertedSource = Converter.Convert(ShaderSource, SourceLen, ShaderCreationAttribs.EntryPoint, ShaderCreationAttribs.Desc.ShaderType); + + ShaderSource = ConvertedSource.c_str(); + SourceLen = static_cast<GLint>( ConvertedSource.length() ); + } + + ShaderStrings.push_back( ShaderSource ); + Lenghts.push_back( SourceLen ); + + // Note: there is a simpler way to create the program: + //m_uiShaderSeparateProg = glCreateShaderProgramv(GL_VERTEX_SHADER, _countof(ShaderStrings), ShaderStrings); + // NOTE: glCreateShaderProgramv() is considered equivalent to both a shader compilation and a program linking + // operation. Since it performs both at the same time, compiler or linker errors can be encountered. However, + // since this function only returns a program object, compiler-type errors will be reported as linker errors + // through the following API: + // GLint isLinked = 0; + // glGetProgramiv(program, GL_LINK_STATUS, &isLinked); + // The log can then be queried in the same way + + // Create empty shader object + auto GLShaderType = GetGLShaderType(m_Desc.ShaderType); + GLObjectWrappers::GLShaderObj ShaderObj(true, GLObjectWrappers::GLShaderObjCreateReleaseHelper(GLShaderType)); + + VERIFY( ShaderStrings.size() == Lenghts.size(), "Incosistent array size" ); + + // Provide source strings (the strings will be saved in internal OpenGL memory) + glShaderSource(ShaderObj, static_cast<GLuint>( ShaderStrings.size() ), ShaderStrings.data(), Lenghts.data() ); + // When the shader is compiled, it will be compiled as if all of the given strings were concatenated end-to-end. + glCompileShader(ShaderObj); + GLint compiled = GL_FALSE; + // Get compilation status + glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &compiled); + if(!compiled) + { + std::stringstream ErrorMsgSS; + ErrorMsgSS << "Failed to compile shader file \""<< ShaderCreationAttribs.FilePath << '\"' << std::endl; + int infoLogLen = 0; + // The function glGetShaderiv() tells how many bytes to allocate; the length includes the NULL terminator. + glGetShaderiv(ShaderObj, GL_INFO_LOG_LENGTH, &infoLogLen); + + if (infoLogLen > 0) + { + std::vector<GLchar> infoLog(infoLogLen); + int charsWritten = 0; + // Get the log. infoLogLen is the size of infoLog. This tells OpenGL how many bytes at maximum it will write + // charsWritten is a return value, specifying how many bytes it actually wrote. One may pass NULL if he + // doesn't care + glGetShaderInfoLog(ShaderObj, infoLogLen, &charsWritten, infoLog.data()); + VERIFY(charsWritten == infoLogLen-1, "Unexpected info log length"); + ErrorMsgSS << "InfoLog:" << std::endl << infoLog.data() << std::endl; + } + LOG_ERROR_AND_THROW(ErrorMsgSS.str().c_str()); + } + + auto DeviceCaps = pDeviceGL->GetDeviceCaps(); + if( DeviceCaps.bSeparableProgramSupported ) + { + m_GlProgObj.Create(); + + // GL_PROGRAM_SEPARABLE parameter must be set before linking! + glProgramParameteri( m_GlProgObj, GL_PROGRAM_SEPARABLE, GL_TRUE ); + glAttachShader( m_GlProgObj, ShaderObj ); + //With separable program objects, interfaces between shader stages may + //involve the outputs from one program object and the inputs from a + //second program object. For such interfaces, it is not possible to + //detect mismatches at link time, because the programs are linked + //separately. When each such program is linked, all inputs or outputs + //interfacing with another program stage are treated as active. The + //linker will generate an executable that assumes the presence of a + //compatible program on the other side of the interface. If a mismatch + //between programs occurs, no GL error will be generated, but some or all + //of the inputs on the interface will be undefined. + glLinkProgram( m_GlProgObj ); + CHECK_GL_ERROR( "glLinkProgram() failed" ); + int IsLinked = GL_FALSE; + glGetProgramiv( m_GlProgObj, GL_LINK_STATUS, (int *)&IsLinked ); + CHECK_GL_ERROR( "glGetProgramiv() failed" ); + if( !IsLinked ) + { + int LengthWithNull = 0, Length = 0; + // Notice that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. + // The length of the info log includes a null terminator. + glGetProgramiv( m_GlProgObj, GL_INFO_LOG_LENGTH, &LengthWithNull ); + + // The maxLength includes the NULL character + std::vector<char> shaderProgramInfoLog( LengthWithNull ); + + // Notice that glGetProgramInfoLog is used, not glGetShaderInfoLog. + glGetProgramInfoLog( m_GlProgObj, LengthWithNull, &Length, &shaderProgramInfoLog[0] ); + VERIFY( Length == LengthWithNull-1, "Incorrect program info log len" ); + LOG_ERROR_AND_THROW( "Failed to link shader program:\n", &shaderProgramInfoLog[0], '\n'); + } + + glDetachShader( m_GlProgObj, ShaderObj ); + + // glDeleteShader() deletes the shader immediately if it is not attached to any program + // object. Otherwise, the shader is flagged for deletion and will be deleted when it is + // no longer attached to any program object. If an object is flagged for deletion, its + // boolean status bit DELETE_STATUS is set to true + ShaderObj.Release(); + + m_GlProgObj.LoadUniforms(); + + // After all program resources are loaded, we can populate shader variable hash map. + // The map contains raw pointers, but none of the arrays will ever change. +#define STORE_SHADER_VARIABLES(ResArr)\ + { \ + auto& Arr = ResArr; \ + for( auto it = Arr.begin(); it != Arr.end(); ++it ) \ + /* HashMapStringKey will make a copy of the string*/ \ + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(it->Name), CGLShaderVariable(this, *it) ) ); \ + } + + STORE_SHADER_VARIABLES(m_GlProgObj.GetUniformBlocks()) + STORE_SHADER_VARIABLES(m_GlProgObj.GetSamplers()) + STORE_SHADER_VARIABLES(m_GlProgObj.GetImages()) + STORE_SHADER_VARIABLES(m_GlProgObj.GetStorageBlocks()) +#undef STORE_SHADER_VARIABLES + + } + else + { + m_GLShaderObj = std::move( ShaderObj ); + } +} + +ShaderGLImpl::~ShaderGLImpl() +{ + static_cast<RenderDeviceGLImpl*>( GetDevice() )->m_PipelineCache.OnDestroyShader(this); +} + +IMPLEMENT_QUERY_INTERFACE( ShaderGLImpl, IID_ShaderGL, TShaderBase ) + +void ShaderGLImpl::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags ) +{ + if( m_GlProgObj ) + m_GlProgObj.BindResources( pResourceMapping, Flags ); + else + { + static bool FirstTime = true; + if( FirstTime ) + { + LOG_WARNING_MESSAGE( "IShader::BindResources() effectively does nothing when separable programs are not supported by the device. Use IDeviceContext::BindShaderResources() instead." ); + FirstTime = false; + } + } +} + +IShaderVariable* ShaderGLImpl::GetShaderVariable( const Char* Name ) +{ + if( !m_GlProgObj ) + { + UNSUPPORTED( "Shader variable queries are currently supported for separable programs only" ); + } + + // Name will be implicitly converted to HashMapStringKey without making a copy + auto it = m_VariableHash.find( Name ); + if( it == m_VariableHash.end() ) + { + LOG_ERROR_MESSAGE( "Shader variable \"", Name, "\" is not found in shader \"", m_Desc.Name ? m_Desc.Name : "", "\". Attempts to set the variable will be silently ignored." ); + return &m_DummyShaderVar; + } + return &it->second; +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp new file mode 100644 index 00000000..42f128df --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp @@ -0,0 +1,71 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "DeviceContextGLImpl.h" +#include "RenderDeviceGLImpl.h" +#include "SwapChainGLImpl.h" + +namespace Diligent +{ +SwapChainGLImpl::SwapChainGLImpl(const SwapChainDesc& SCDesc, + RenderDeviceGLImpl* pRenderDeviceGL, + DeviceContextGLImpl* pImmediateContextGL) : + TSwapChainBase( pRenderDeviceGL, pImmediateContextGL, pRenderDeviceGL->m_GLContext.GetSwapChainDesc() ) +{ +} + +SwapChainGLImpl::~SwapChainGLImpl() +{ +} + +IMPLEMENT_QUERY_INTERFACE( SwapChainGLImpl, IID_SwapChainGL, TSwapChainBase ) + +void SwapChainGLImpl::Present() +{ + auto *pDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pRenderDevice.RawPtr()); + pDeviceGL->m_GLContext.SwapBuffers(); +} + +void SwapChainGLImpl::Resize( Uint32 NewWidth, Uint32 NewHeight ) +{ + if( TSwapChainBase::Resize( NewWidth, NewHeight ) ) + { + auto pDeviceContext = m_wpDeviceContext.Lock(); + VERIFY( pDeviceContext, "Immediate context has been released" ); + if( pDeviceContext ) + { + auto *pImmediateCtxGL = ValidatedCast<DeviceContextGLImpl>( pDeviceContext.RawPtr() ); + bool bIsDefaultFBBound = pImmediateCtxGL->IsDefaultFBBound(); + + // To update the viewport is the only thing we need to do in OpenGL + if( bIsDefaultFBBound ) + { + // Update viewport + pImmediateCtxGL->SetViewports( 1, nullptr, 0, 0 ); + } + } + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp new file mode 100644 index 00000000..a853c7ee --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp @@ -0,0 +1,264 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "TexRegionRender.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "MapHelper.h" + +namespace Diligent +{ + static const Char* VertexShaderSource = + { + //To use any built-in input or output in the gl_PerVertex and + //gl_PerFragment blocks in separable program objects, shader code must + //redeclare those blocks prior to use. + // + // Declaring this block causes compilation error on NVidia GLES + "#ifndef GL_ES \n" + "out gl_PerVertex \n" + "{ \n" + " vec4 gl_Position; \n" + "}; \n" + "#endif \n" + + "void main() \n" + "{ \n" + " vec4 Bounds = vec4(-1.0, -1.0, 1.0, 1.0); \n" + " vec2 PosXY[4] = \n" + " { \n" + " Bounds.xy, \n" + " Bounds.xw, \n" + " Bounds.zy, \n" + " Bounds.zw \n" + " }; \n" + " gl_Position = vec4(PosXY[gl_VertexID], 0.0, 1.0);\n" + "} \n" + }; + + TexRegionRender::TexRegionRender( class RenderDeviceGLImpl *pDeviceGL ) : + m_OrigStencilRef(0), + m_OrigSamplesBlendMask(0), + m_NumRenderTargets(0) + { + memset( m_OrigBlendFactors, 0, sizeof(m_OrigBlendFactors) ); + memset( m_pOrigRTVs, 0, sizeof( m_pOrigRTVs ) ); + + ShaderCreationAttribs ShaderAttrs; + ShaderAttrs.Desc.Name = "TexRegionRender : Vertex shader"; + ShaderAttrs.Desc.ShaderType = SHADER_TYPE_VERTEX; + ShaderAttrs.Source = VertexShaderSource; + pDeviceGL->CreateShader( ShaderAttrs, &m_pVertexShader, + true // We must indicate the shader is internal device object + ); + + static const char* SamplerType[TEXTURE_TYPE_NUM_TYPES] = {}; + SamplerType[TEXTURE_TYPE_1D] = "sampler1D"; + SamplerType[TEXTURE_TYPE_1D_ARRAY] = "sampler1DArray"; + SamplerType[TEXTURE_TYPE_2D] = "sampler2D"; + SamplerType[TEXTURE_TYPE_2D_ARRAY] = "sampler2DArray", + SamplerType[TEXTURE_TYPE_3D] = "sampler3D"; + // There is no texelFetch() for texture cube [array] + //SamplerType[TEXTURE_TYPE_CUBE] = "samplerCube"; + //SamplerType[TEXTURE_TYPE_CUBE_ARRAY] = "smaplerCubeArray"; + + static const char* SrcLocations[TEXTURE_TYPE_NUM_TYPES] = {}; + SrcLocations[TEXTURE_TYPE_1D] = "int(gl_FragCoord.x) + Constants.x"; + SrcLocations[TEXTURE_TYPE_1D_ARRAY] = "ivec2(int(gl_FragCoord.x) + Constants.x, Constants.z)"; + SrcLocations[TEXTURE_TYPE_2D] = "ivec2(gl_FragCoord.xy) + Constants.xy"; + SrcLocations[TEXTURE_TYPE_2D_ARRAY] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)", + SrcLocations[TEXTURE_TYPE_3D] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)"; + // There is no texelFetch() for texture cube [array] + //CoordDim[TEXTURE_TYPE_CUBE] = "ivec2(gl_FragCoord.xy)"; + //CoordDim[TEXTURE_TYPE_CUBE_ARRAY] = "ivec2(gl_FragCoord.xy)"; + + BufferDesc CBDesc; + CBDesc.uiSizeInBytes = sizeof(Int32)*4; + CBDesc.Usage = USAGE_DYNAMIC; + CBDesc.BindFlags = BIND_UNIFORM_BUFFER; + CBDesc.CPUAccessFlags = CPU_ACCESS_WRITE; + pDeviceGL->CreateBuffer( CBDesc, BufferData(), &m_pConstantBuffer, + true // We must indicate the buffer is internal device object + ); + + static const char* CmpTypePrefix[3] = { "", "i", "u" }; + for( Int32 Dim = TEXTURE_TYPE_2D; Dim <= TEXTURE_TYPE_3D; ++Dim ) + { + const auto *SamplerDim = SamplerType[Dim]; + const auto *SrcLocation = SrcLocations[Dim]; + for( Int32 Fmt = 0; Fmt < 3; ++Fmt ) + { + const auto *Prefix = CmpTypePrefix[Fmt]; + String Name = "TexRegionRender : Pixel shader "; + Name.append( Prefix ); + Name.append( SamplerDim ); + ShaderAttrs.Desc.Name = Name.c_str(); + ShaderAttrs.Desc.ShaderType = SHADER_TYPE_PIXEL; + + std::stringstream SourceSS; + SourceSS << "uniform " << Prefix << SamplerDim << " gSourceTex;\n" + << "layout( location = 0 ) out " << Prefix << "vec4 Out;\n" + << "uniform cbConstants\n" + << "{\n" + << " ivec4 Constants;\n" + << "};\n" + << "void main()\n" + << "{\n" + << " Out = texelFetch( gSourceTex, " << SrcLocation << ", Constants.w );\n" + << "}\n"; + + auto Source = SourceSS.str(); + ShaderAttrs.Source = Source.c_str(); + auto &FragmetShader = m_pFragmentShaders[Dim*3 + Fmt]; + pDeviceGL->CreateShader( ShaderAttrs, &FragmetShader, + true // We must indicate the shader is internal device object + ); + FragmetShader->GetShaderVariable( "cbConstants" )->Set( m_pConstantBuffer ); + } + } + + RasterizerStateDesc RSDesc; + RSDesc.CullMode = CULL_MODE_NONE; + RSDesc.FillMode = FILL_MODE_SOLID; + RSDesc.Name = "TexRegionRender : Solid fill no cull RS"; + pDeviceGL->CreateRasterizerState( RSDesc, &m_pSolidFillNoCullRS, + true // We must indicate the RS state is internal device object + ); + + DepthStencilStateDesc DSSDesc; + DSSDesc.Name = "TexRegionRender : disable depth DSS"; + DSSDesc.DepthEnable = false; + DSSDesc.DepthWriteEnable = false; + pDeviceGL->CreateDepthStencilState( DSSDesc, &m_pDisableDetphDS, + true // We must indicate the DSS state is internal device object + ); + + BlendStateDesc BSDesc; + BSDesc.Name = "TexRegionRender : default BS"; + pDeviceGL->CreateBlendState(BSDesc, &m_pDefaultBS, + true // We must indicate the BS state is internal device object + ); + } + + void TexRegionRender::SetStates( DeviceContextGLImpl *pCtxGL ) + { + Uint32 NumShaders = 0; + pCtxGL->GetShaders( nullptr, NumShaders ); + m_pOrigShaders.resize( NumShaders ); + pCtxGL->GetShaders( m_pOrigShaders.data(), NumShaders ); + + pCtxGL->GetRenderTargets( m_NumRenderTargets, m_pOrigRTVs, &m_pOrigDSV ); + + Uint32 NumViewports = 0; + pCtxGL->GetViewports( NumViewports, nullptr ); + m_OrigViewports.resize(NumViewports); + pCtxGL->GetViewports( NumViewports, m_OrigViewports.data() ); + + pCtxGL->GetDepthStencilState(&m_pOrigDS, m_OrigStencilRef); + VERIFY( m_pOrigDS, "At least default depth-stencil state must be bound" ); + + pCtxGL->GetBlendState(&m_pOrigBS, m_OrigBlendFactors, m_OrigSamplesBlendMask); + VERIFY( m_pOrigBS, "At least default blend state must be bound" ); + + pCtxGL->GetRasterizerState(&m_pOrigRS); + VERIFY( m_pOrigRS, "At least default rasterizer state must be bound" ); + + pCtxGL->SetDepthStencilState( m_pDisableDetphDS, m_OrigStencilRef ); + pCtxGL->SetBlendState(m_pDefaultBS, m_OrigBlendFactors, m_OrigSamplesBlendMask); + pCtxGL->SetRasterizerState(m_pSolidFillNoCullRS); + + } + + void TexRegionRender::RestoreStates( DeviceContextGLImpl *pCtxGL ) + { + pCtxGL->SetShaders( m_pOrigShaders.data(), (Uint32)m_pOrigShaders.size() ); + for( auto pSh = m_pOrigShaders.begin(); pSh != m_pOrigShaders.end(); ++pSh ) + (*pSh)->Release(); + m_pOrigShaders.clear(); + + pCtxGL->SetRenderTargets( m_NumRenderTargets, m_pOrigRTVs, m_pOrigDSV ); + for( Uint32 rt = 0; rt < _countof( m_pOrigRTVs ); ++rt ) + { + if( m_pOrigRTVs[rt] ) + m_pOrigRTVs[rt]->Release(); + m_pOrigRTVs[rt] = nullptr; + } + m_pOrigDSV.Release(); + + pCtxGL->SetViewports( (Uint32)m_OrigViewports.size(), m_OrigViewports.data(), 0, 0 ); + + pCtxGL->SetDepthStencilState( m_pOrigDS, m_OrigStencilRef ); + m_pOrigDS.Release(); + + pCtxGL->SetBlendState(m_pOrigBS, m_OrigBlendFactors, m_OrigSamplesBlendMask); + m_pOrigBS.Release(); + + pCtxGL->SetRasterizerState(m_pOrigRS); + m_pOrigRS.Release(); + } + + void TexRegionRender::Render( DeviceContextGLImpl *pCtxGL, + ITextureView *pSrcSRV, + TEXTURE_TYPE TexType, + TEXTURE_FORMAT TexFormat, + Int32 DstToSrcXOffset, + Int32 DstToSrcYOffset, + Int32 SrcZ, + Int32 SrcMipLevel) + { + { + MapHelper< int > pConstant( pCtxGL, m_pConstantBuffer, MAP_WRITE_DISCARD, 0 ); + pConstant[0] = DstToSrcXOffset; + pConstant[1] = DstToSrcYOffset; + pConstant[2] = SrcZ; + pConstant[3] = SrcMipLevel; + } + + const auto &TexFmtAttribs = GetTextureFormatAttribs(TexFormat); + Uint32 FSInd = TexType * 3; + if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_SINT ) + FSInd += 1; + else if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_UINT ) + FSInd += 2; + + if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_SNORM ) + { + LOG_WARNING_MESSAGE("CopyData() is performed by rendering to texture.\n" + "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero.") + } + + IShader *ppShaders[2] = { m_pVertexShader, m_pFragmentShaders[FSInd] }; + auto SrcTexVar = ppShaders[1]->GetShaderVariable( "gSourceTex" ); + SrcTexVar->Set( pSrcSRV ); + + pCtxGL->SetShaders( ppShaders, _countof(ppShaders) ); + DrawAttribs DrawAttrs; + DrawAttrs.NumVertices = 4; + DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + pCtxGL->Draw( DrawAttrs ); + + SrcTexVar->Set( nullptr ); + } +} diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp new file mode 100644 index 00000000..8680f788 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp @@ -0,0 +1,156 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "Texture1DArray_OGL.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "GLTypeConversions.h" + + +namespace Diligent +{ + +Texture1DArray_OGL::Texture1DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/, + bool bIsDeviceInternal /*= false*/) : + TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) +{ + auto &ContextState = pDeviceContext->GetContextState(); + + m_BindTarget = GL_TEXTURE_1D_ARRAY; + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + // levels format width height + glTexStorage2D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.ArraySize); + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 1D texture array"); + // When target is GL_TEXTURE_1D_ARRAY, calling glTexStorage2D() is equivalent to the following code: + //for (i = 0; i < levels; i++) + //{ + // glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL); + // width = max(1, (width / 2)); + //} + + SetDefaultGLParameters(); + + if( InitData.pSubResources ) + { + if( m_Desc.MipLevels * m_Desc.ArraySize == InitData.NumSubresources ) + { + for(Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice ) + { + for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + { + Box DstBox(0, std::max(m_Desc.Width>>Mip, 1U), + 0, 1 ); + // UpdateData() is a virtual function. If we try to call it through vtbl from here, + // we will get into TextureBaseGL::UpdateData(), because instance of Texture1DArray_OGL + // is not fully constructed yet. + // To call the required function, we need to explicitly specify the class: + Texture1DArray_OGL::UpdateData(pDeviceContext, Mip, Slice, DstBox, InitData.pSubResources[Slice*m_Desc.MipLevels + Mip]); + } + } + } + else + { + UNEXPECTED("Incorrect number of subresources"); + } + } + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj( false ) ); +} + +Texture1DArray_OGL::~Texture1DArray_OGL() +{ +} + +void Texture1DArray_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); + + auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); + auto &ContextState = pDeviceContextGL->GetContextState(); + + // GL_TEXTURE_UPDATE_BARRIER_BIT: + // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, + // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect + // data written by shaders prior to the barrier. Additionally, texture writes from these + // commands issued after the barrier will not execute until all shader writes initiated prior + // to the barrier complete + TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + + ContextState.BindTexture( -1, m_BindTarget, m_GlTexture ); + + // Transfers to OpenGL memory are called unpack operations + // If there is a buffer bound to GL_PIXEL_UNPACK_BUFFER target, then all the pixel transfer + // operations will be performed from this buffer. We need to make sure none is bound + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + auto TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0 ); + + glTexSubImage2D(m_BindTarget, MipLevel, + DstBox.MinX, + Slice, + DstBox.MaxX - DstBox.MinX, + 1, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + SubresData.pData); + + CHECK_GL_ERROR("Failed to update subimage data"); + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +void Texture1DArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +{ + if( ViewDesc.NumArraySlices == m_Desc.ArraySize ) + { + glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 1D array to draw framebuffer" ); + glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 1D array to read framebuffer" ); + } + else if( ViewDesc.NumArraySlices == 1 ) + { + // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, + // cube map array texture, or multisample array texture. + glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); + CHECK_GL_ERROR( "Failed to attach texture 1D array to draw framebuffer" ); + glFramebufferTextureLayer( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); + CHECK_GL_ERROR( "Failed to attach texture 1D array to read framebuffer" ); + } + else + { + UNEXPECTED( "Only one slice or the entire texture array can be attached to a framebuffer" ); + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp new file mode 100644 index 00000000..5b9a0b9a --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp @@ -0,0 +1,135 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "Texture1D_OGL.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "GLTypeConversions.h" + +namespace Diligent +{ + +Texture1D_OGL::Texture1D_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/, + bool bIsDeviceInternal /*= false*/) : + TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) +{ + auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pDeviceContext); + auto &ContextState = pDeviceContextGL->GetContextState(); + + m_BindTarget = GL_TEXTURE_1D; + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + // levels format width + glTexStorage1D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width); + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 1D texture"); + // When target is GL_TEXTURE_1D, calling glTexStorage1D is equivalent to the following pseudo-code: + //for (i = 0; i < levels; i++) + //{ + // glTexImage1D(target, i, internalformat, width, 0, format, type, NULL); + // width = max(1, (width / 2)); + //} + + SetDefaultGLParameters(); + + if( InitData.pSubResources ) + { + if( m_Desc.MipLevels == InitData.NumSubresources ) + { + for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + { + Box DstBox(0, std::max(m_Desc.Width>>Mip, 1U), + 0, 1); + // UpdateData() is a virtual function. If we try to call it through vtbl from here, + // we will get into TextureBaseGL::UpdateData(), because instance of Texture1D_OGL + // is not fully constructed yet. + // To call the required function, we need to explicitly specify the class: + Texture1D_OGL::UpdateData( pDeviceContext, Mip, 0, DstBox, InitData.pSubResources[Mip] ); + } + } + else + { + UNEXPECTED( "Incorrect number of subresources" ); + } + } + + ContextState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +Texture1D_OGL::~Texture1D_OGL() +{ +} + +void Texture1D_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); + + auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); + auto &ContextState = pDeviceContextGL->GetContextState(); + + // GL_TEXTURE_UPDATE_BARRIER_BIT: + // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, + // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect + // data written by shaders prior to the barrier. Additionally, texture writes from these + // commands issued after the barrier will not execute until all shader writes initiated prior + // to the barrier complete + TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + + ContextState.BindTexture( -1, m_BindTarget, m_GlTexture ); + + // Transfers to OpenGL memory are called unpack operations + // If there is a buffer bound to GL_PIXEL_UNPACK_BUFFER target, then all the pixel transfer + // operations will be performed from this buffer. We need to make sure none is bound + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + auto TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0 ); + + glTexSubImage1D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MaxX - DstBox.MinX, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + SubresData.pData); + CHECK_GL_ERROR("Failed to update subimage data"); + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +void Texture1D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +{ + // For glFramebufferTexture1D(), if texture name is not zero, then texture target must be GL_TEXTURE_1D + glFramebufferTexture1D( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 1D to draw framebuffer" ); + glFramebufferTexture1D( GL_READ_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 1D to read framebuffer" ); +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp new file mode 100644 index 00000000..fefa51e5 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp @@ -0,0 +1,217 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "Texture2DArray_OGL.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "GLTypeConversions.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +Texture2DArray_OGL::Texture2DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/, + bool bIsDeviceInternal /*= false*/) : + TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) +{ + auto &ContextState = pDeviceContext->GetContextState(); + + if( m_Desc.SampleCount > 1 ) + { + m_BindTarget = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + // format width height depth + glTexStorage3DMultisample(m_BindTarget, m_Desc.SampleCount, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.ArraySize, TRUE); + // The last parameter specifies whether the image will use identical sample locations and the same number of + // samples for all texels in the image, and the sample locations will not depend on the internal format or size + // of the image. + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 2D multisample texture array"); + // * An INVALID_ENUM error is generated if sizedinternalformat is not colorrenderable, + // depth - renderable, or stencil - renderable + // * An INVALID_OPERATION error is generated if samples is greater than the maximum number of samples + // supported for this target and internalformat. The maximum number of samples supported can be + // determined by calling glGetInternalformativ with a pname of GL_SAMPLES + + SetDefaultGLParameters(); + } + else + { + m_BindTarget = GL_TEXTURE_2D_ARRAY; + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + // levels format width height depth + glTexStorage3D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.ArraySize); + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 2D texture array"); + // When target is GL_TEXTURE_2D_ARRAY, calling glTexStorage3D is equivalent to the following pseudo-code: + //for (i = 0; i < levels; i++) + //{ + // glTexImage3D(target, i, internalformat, width, height, depth, 0, format, type, NULL); + // width = max(1, (width / 2)); + // height = max(1, (height / 2)); + //} + + SetDefaultGLParameters(); + + if( InitData.pSubResources ) + { + if( m_Desc.MipLevels * m_Desc.ArraySize == InitData.NumSubresources ) + { + for(Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice) + { + for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + { + Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U) ); + // UpdateData() is a virtual function. If we try to call it through vtbl from here, + // we will get into TextureBaseGL::UpdateData(), because instance of Texture2DArray_OGL + // is not fully constructed yet. + // To call the required function, we need to explicitly specify the class: + Texture2DArray_OGL::UpdateData(pDeviceContext, Mip, Slice, DstBox, InitData.pSubResources[Slice*m_Desc.MipLevels + Mip]); + } + } + } + else + { + UNEXPECTED("Incorrect number of subresources"); + } + } + + } + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +Texture2DArray_OGL::~Texture2DArray_OGL() +{ +} + +void Texture2DArray_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); + + auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); + auto &ContextState = pDeviceContextGL->GetContextState(); + + // GL_TEXTURE_UPDATE_BARRIER_BIT: + // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, + // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect + // data written by shaders prior to the barrier. Additionally, texture writes from these + // commands issued after the barrier will not execute until all shader writes initiated prior + // to the barrier complete + TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + // Transfers to OpenGL memory are called unpack operations + // If there is a buffer bound to GL_PIXEL_UNPACK_BUFFER target, then all the pixel transfer + // operations will be performed from this buffer. We need to make sure none is bound + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + auto TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + if( TransferAttribs.IsCompressed ) + { + VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == std::max(m_Desc.Width >>MipLevel, 1U)) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == std::max(m_Desc.Height>>MipLevel, 1U)), + "Compressed texture update region must be 4 pixel-aligned" ); + const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); + auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * FmtAttribs.ComponentSize; + VERIFY( SubresData.Stride == BlockBytesInRow, + "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")" ); + + //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); + glCompressedTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + Slice, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + 1, + // The format must be the same compressed-texture format previously + // specified by glTexStorage2D() (thank you OpenGL for another useless + // parameter that is nothing but the source of confusion), otherwise + // INVALID_OPERATION error is generated. + m_GLTexFormat, + // An INVALID_VALUE error is generated if imageSize is not consistent with + // the format, dimensions, and contents of the compressed image( too little or + // too much data ), + ((DstBox.MaxY - DstBox.MinY + 3)/4) * SubresData.Stride, + SubresData.pData); + } + else + { + const auto TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); + const auto PixelSize = TexFmtInfo.NumComponents * TexFmtInfo.ComponentSize; + VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0 ); + + glTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + Slice, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + 1, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + SubresData.pData); + } + CHECK_GL_ERROR("Failed to update subimage data"); + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +void Texture2DArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +{ + if( ViewDesc.NumArraySlices == m_Desc.ArraySize ) + { + glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 2D array to draw framebuffer" ); + glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 2D array to read framebuffer" ); + } + else if( ViewDesc.NumArraySlices == 1 ) + { + // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, + // cube map array texture, or multisample array texture. + glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); + CHECK_GL_ERROR( "Failed to attach texture 2D array to draw framebuffer" ); + glFramebufferTextureLayer( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); + CHECK_GL_ERROR( "Failed to attach texture 2D array to read framebuffer" ); + } + else + { + UNEXPECTED( "Only one slice or the entire texture array can be attached to a framebuffer" ); + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp new file mode 100644 index 00000000..511085ca --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp @@ -0,0 +1,197 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "Texture2D_OGL.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "GLTypeConversions.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +Texture2D_OGL::Texture2D_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/, + bool bIsDeviceInternal /*= false*/) : + TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) +{ + auto &ContextState = pDeviceContext->GetContextState(); + + if( m_Desc.SampleCount > 1 ) + { + m_BindTarget = GL_TEXTURE_2D_MULTISAMPLE; + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + // format width height depth + glTexStorage2DMultisample(m_BindTarget, m_Desc.SampleCount, m_GLTexFormat, m_Desc.Width, m_Desc.Height, GL_TRUE); + // The last parameter specifies whether the image will use identical sample locations and the same number of + // samples for all texels in the image, and the sample locations will not depend on the internal format or size + // of the image. + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 2D multisample texture"); + // * An INVALID_ENUM error is generated if sizedinternalformat is not colorrenderable, + // depth - renderable, or stencil - renderable + // * An INVALID_OPERATION error is generated if samples is greater than the maximum number of samples + // supported for this target and internalformat. The maximum number of samples supported can be + // determined by calling glGetInternalformativ with a pname of GL_SAMPLES + + SetDefaultGLParameters(); + + VERIFY( InitData.pSubResources == nullptr, "Multisampled textures cannot be modified directly" ); + } + else + { + m_BindTarget = GL_TEXTURE_2D; + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + // levels format width height + glTexStorage2D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height); + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 2D texture"); + // When target is GL_TEXTURE_2D, calling glTexStorage2D is equivalent to the following pseudo-code: + //for (i = 0; i < levels; i++) + //{ + // glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL); + // width = max(1, (width / 2)); + // height = max(1, (height / 2)); + //} + + SetDefaultGLParameters(); + + if( InitData.pSubResources ) + { + if( m_Desc.MipLevels == InitData.NumSubresources ) + { + for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + { + Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U) ); + // UpdateData() is a virtual function. If we try to call it through vtbl from here, + // we will get into TextureBaseGL::UpdateData(), because instance of Texture2D_OGL + // is not fully constructed yet. + // To call the required function, we need to explicitly specify the class: + Texture2D_OGL::UpdateData( pDeviceContext, Mip, 0, DstBox, InitData.pSubResources[Mip] ); + } + } + else + { + UNEXPECTED("Incorrect number of subresources"); + } + } + } + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +Texture2D_OGL::~Texture2D_OGL() +{ +} + +void Texture2D_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); + + auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); + auto &ContextState = pDeviceContextGL->GetContextState(); + + // GL_TEXTURE_UPDATE_BARRIER_BIT: + // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, + // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect + // data written by shaders prior to the barrier. Additionally, texture writes from these + // commands issued after the barrier will not execute until all shader writes initiated prior + // to the barrier complete + TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + // Transfers to OpenGL memory are called unpack operations + // If there is a buffer bound to GL_PIXEL_UNPACK_BUFFER target, then all the pixel transfer + // operations will be performed from this buffer. We need to make sure none is bound + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + auto TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + if( TransferAttribs.IsCompressed ) + { + VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == std::max(m_Desc.Width >>MipLevel, 1U)) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == std::max(m_Desc.Height>>MipLevel, 1U)), + "Compressed texture update region must be 4 pixel-aligned" ); + const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); + auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * FmtAttribs.ComponentSize; + VERIFY( SubresData.Stride == BlockBytesInRow, + "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")" ); + + //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); + glCompressedTexSubImage2D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + // The format must be the same compressed-texture format previously + // specified by glTexStorage2D() (thank you OpenGL for another useless + // parameter that is nothing but the source of confusion), otherwise + // INVALID_OPERATION error is generated. + m_GLTexFormat, + // An INVALID_VALUE error is generated if imageSize is not consistent with + // the format, dimensions, and contents of the compressed image( too little or + // too much data ), + ((DstBox.MaxY - DstBox.MinY + 3)/4) * SubresData.Stride, + SubresData.pData); + } + else + { + const auto& TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); + const auto PixelSize = TexFmtInfo.NumComponents * TexFmtInfo.ComponentSize; + VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + + glTexSubImage2D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + SubresData.pData); + } + CHECK_GL_ERROR("Failed to update subimage data"); + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +void Texture2D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +{ + // For glFramebufferTexture2D(), if texture name is not zero, then texture target must be GL_TEXTURE_2D, + // GL_TEXTURE_RECTANGLE or one of the 6 cubemap face targets GL_TEXTURE_CUBE_MAP_POSITIVE_X, ... + glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 2D to draw framebuffer" ); + glFramebufferTexture2D( GL_READ_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 2D to read framebuffer" ); +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp new file mode 100644 index 00000000..03913c3d --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp @@ -0,0 +1,171 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "Texture3D_OGL.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "GLTypeConversions.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +Texture3D_OGL::Texture3D_OGL( class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/, + bool bIsDeviceInternal /*= false*/) : + TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) +{ + auto &ContextState = pDeviceContext->GetContextState(); + + m_BindTarget = GL_TEXTURE_3D; + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + // levels format width height depth + glTexStorage3D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.Depth); + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 3D texture"); + // When target is GL_TEXTURE_3D, calling glTexStorage3D is equivalent to the following pseudo-code: + //for (i = 0; i < levels; i++) + //{ + // glTexImage3D(target, i, internalformat, width, height, depth, 0, format, type, NULL); + // width = max(1, (width / 2)); + // height = max(1, (height / 2)); + // depth = max(1, (depth / 2)); + // + + SetDefaultGLParameters(); + + if( InitData.pSubResources ) + { + if( m_Desc.MipLevels == InitData.NumSubresources ) + { + for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + { + Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U), + 0, std::max(m_Desc.Depth >>Mip, 1U)); + // UpdateData() is a virtual function. If we try to call it through vtbl from here, + // we will get into TextureBaseGL::UpdateData(), because instance of Texture3D_OGL + // is not fully constructed yet. + // To call the required function, we need to explicitly specify the class: + Texture3D_OGL::UpdateData( pDeviceContext, Mip, 0, DstBox, InitData.pSubResources[Mip] ); + } + } + else + { + UNEXPECTED("Incorrect number of subresources"); + } + } + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +Texture3D_OGL::~Texture3D_OGL() +{ +} + + +void Texture3D_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); + + auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); + auto &ContextState = pDeviceContextGL->GetContextState(); + + // GL_TEXTURE_UPDATE_BARRIER_BIT: + // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, + // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect + // data written by shaders prior to the barrier. Additionally, texture writes from these + // commands issued after the barrier will not execute until all shader writes initiated prior + // to the barrier complete + TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + // Transfers to OpenGL memory are called unpack operations + // If there is a buffer bound to GL_PIXEL_UNPACK_BUFFER target, then all the pixel transfer + // operations will be performed from this buffer. We need to make sure none is bound + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + auto TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); + + const auto TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); + const auto PixelSize = TexFmtInfo.NumComponents * TexFmtInfo.ComponentSize; + VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); + + VERIFY( (SubresData.DepthStride % SubresData.Stride)==0, "Depth stride is not multiple of stride" ); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, SubresData.DepthStride / SubresData.Stride); + + glTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + DstBox.MinZ, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + DstBox.MaxZ - DstBox.MinZ, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + SubresData.pData); + + CHECK_GL_ERROR("Failed to update subimage data"); + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +void Texture3D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +{ + auto NumDepthSlicesInMip = m_Desc.Depth >> ViewDesc.MostDetailedMip; + if( ViewDesc.NumDepthSlices == NumDepthSlicesInMip ) + { + glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 3D to draw framebuffer" ); + glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture 3D to read framebuffer" ); + } + else if( ViewDesc.NumDepthSlices == 1 ) + { + // For glFramebufferTexture3D(), if texture name is not zero, then texture target must be GL_TEXTURE_3D + //glFramebufferTexture3D( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice ); + //glFramebufferTexture3D( GL_READ_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice ); + + // On Android (at least on Intel HW), glFramebufferTexture3D() runs without errors, but the + // FBO turns out to be incomplete. glFramebufferTextureLayer() seems to work fine. + glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice ); + CHECK_GL_ERROR( "Failed to attach texture 3D to draw framebuffer" ); + glFramebufferTextureLayer( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice ); + CHECK_GL_ERROR( "Failed to attach texture 3D to read framebuffer" ); + } + else + { + UNEXPECTED( "Only one slice or the entire 3D texture can be attached to a framebuffer" ); + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp new file mode 100644 index 00000000..0e893369 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp @@ -0,0 +1,433 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "TextureBaseGL.h" +#include "RenderDeviceGLImpl.h" +#include "GLTypeConversions.h" +#include "TextureViewGLImpl.h" +#include "GLContextState.h" +#include "DeviceContextGLImpl.h" + +namespace Diligent +{ + +TextureBaseGL::TextureBaseGL(class RenderDeviceGLImpl *pDeviceGL, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/, bool bIsDeviceInternal /*= false*/) : + TTextureBase( pDeviceGL, TexDesc, bIsDeviceInternal ), + m_GlTexture(true), // Create Texture immediately + m_BindTarget(0), + m_GLTexFormat( TexFormatToGLInternalTexFormat(m_Desc.Format, m_Desc.BindFlags) ) + //m_uiMapTarget(0) +{ + VERIFY( m_GLTexFormat != 0, "Unsupported texture format" ); + if( TexDesc.Usage == USAGE_STATIC && InitData.pSubResources == nullptr ) + LOG_ERROR_AND_THROW("Static Texture must be initialized with data at creation time"); +} + +TextureBaseGL::~TextureBaseGL() +{ + // Release all FBOs that contain current texture + // NOTE: we cannot check if BIND_RENDER_TARGET + // flag is set, because CopyData() can bind + // texture as render target even when no flag + // is set + static_cast<RenderDeviceGLImpl*>( GetDevice() )->m_FBOCache.OnReleaseTexture(this); +} + +IMPLEMENT_QUERY_INTERFACE( TextureBaseGL, IID_TextureGL, TTextureBase ) + + +void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDesc, class ITextureView **ppView, bool bIsDefaultView ) +{ + VERIFY( ppView != nullptr, "Null pointer provided" ); + if( !ppView )return; + VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + + *ppView = nullptr; + + try + { + auto ViewDesc = OrigViewDesc; + CorrectTextureViewDesc(ViewDesc); + + // http://www.opengl.org/wiki/Texture_Storage#Texture_views + + GLenum GLViewFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format, m_Desc.BindFlags ); + VERIFY( GLViewFormat != 0, "Unsupported texture format" ); + + TextureViewGLImpl *pViewOGL = nullptr; + if( ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE ) + { + bool bIsFullTextureView = + ViewDesc.TextureType == m_Desc.Type && + ViewDesc.Format == CorrectTextureViewFormat( m_Desc.Format, ViewDesc.ViewType ) && + ViewDesc.MostDetailedMip == 0 && + ViewDesc.NumMipLevels == m_Desc.MipLevels && + ViewDesc.FirstArraySlice == 0 && + ViewDesc.NumArraySlices == m_Desc.ArraySize; + + pViewOGL = new TextureViewGLImpl( GetDevice(), ViewDesc, this, + !bIsFullTextureView, // Create OpenGL texture view object if view + // does not address the whole texture + bIsDefaultView + ); + if( !bIsFullTextureView ) + { + GLenum GLViewTarget = 0; + switch(ViewDesc.TextureType) + { + case TEXTURE_TYPE_1D: + GLViewTarget = GL_TEXTURE_1D; + ViewDesc.NumArraySlices = 1; + break; + + case TEXTURE_TYPE_1D_ARRAY: + GLViewTarget = GL_TEXTURE_1D_ARRAY; + break; + + case TEXTURE_TYPE_2D: + GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; + ViewDesc.NumArraySlices = 1; + break; + + case TEXTURE_TYPE_2D_ARRAY: + GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY; + break; + + case TEXTURE_TYPE_3D: + GLViewTarget = GL_TEXTURE_3D; + break; + + default: UNEXPECTED("Unsupported texture view type"); + } + + glTextureView( pViewOGL->GetHandle(), GLViewTarget, m_GlTexture, GLViewFormat, ViewDesc.MostDetailedMip, ViewDesc.NumMipLevels, ViewDesc.FirstArraySlice, ViewDesc.NumArraySlices ); + CHECK_GL_ERROR_AND_THROW( "Failed to create texture view" ); + } + } + else if( ViewDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS ) + { + VERIFY( ViewDesc.NumArraySlices == 1 || ViewDesc.NumArraySlices == m_Desc.ArraySize, + "Only single array/depth slice or the whole texture can be bound as UAV in OpenGL"); + VERIFY( ViewDesc.AccessFlags != 0, "At least one access flag must be specified" ); + pViewOGL = new TextureViewGLImpl( GetDevice(), ViewDesc, this, + false, // Do NOT create texture view OpenGL object + bIsDefaultView + ); + } + else if( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET ) + { + VERIFY( ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as RTV" ); + pViewOGL = new TextureViewGLImpl( GetDevice(), ViewDesc, this, + false, // Do NOT create texture view OpenGL object + bIsDefaultView + ); + } + else if( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL ) + { + VERIFY( ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as DSV" ); + pViewOGL = new TextureViewGLImpl( GetDevice(), ViewDesc, this, + false, // Do NOT create texture view OpenGL object + bIsDefaultView + ); + } + + if( bIsDefaultView ) + *ppView = pViewOGL; + else + { + if( pViewOGL ) + { + pViewOGL->QueryInterface( IID_TextureView, reinterpret_cast<IObject**>(ppView) ); + } + } + } + catch( const std::runtime_error& ) + { + const auto *ViewTypeName = GetTexViewTypeLiteralName(OrigViewDesc.ViewType); + LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for texture \"", m_Desc.Name ? m_Desc.Name : "", "\"" ) + } +} + + +void TextureBaseGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + TTextureBase::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); +} + +//void TextureBaseGL :: UpdateData(Uint32 Offset, Uint32 Size, const PVoid pData) +//{ +// CTexture::UpdateData(Offset, Size, pData); +// +// glBindTexture(GL_ARRAY_Texture, m_GlTexture); +// glTextureSubData(GL_ARRAY_Texture, Offset, Size, pData); +// glBindTexture(GL_ARRAY_Texture, 0); +//} +// + +void TextureBaseGL :: CopyData(IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ) +{ + auto *pDeviceCtxGL = ValidatedCast<DeviceContextGLImpl>( pContext ); + auto *pSrcTextureGL = ValidatedCast<TextureBaseGL>( pSrcTexture ); + const auto& SrcTexDesc = pSrcTextureGL->GetDesc(); + + Box SrcBox; + if( pSrcBox == nullptr ) + { + SrcBox.MaxX = std::max( SrcTexDesc.Width >> SrcMipLevel, 1u ); + if( SrcTexDesc.Type == TEXTURE_TYPE_1D || + SrcTexDesc.Type == TEXTURE_TYPE_1D_ARRAY ) + SrcBox.MaxY = 1; + else + SrcBox.MaxY = std::max( SrcTexDesc.Height >> SrcMipLevel, 1u ); + + if( SrcTexDesc.Type == TEXTURE_TYPE_3D ) + SrcBox.MaxZ = std::max( SrcTexDesc.Depth >> SrcMipLevel, 1u ); + else + SrcBox.MaxZ = 1; + pSrcBox = &SrcBox; + } + + TTextureBase::CopyData( pContext, pSrcTexture, SrcMipLevel, SrcSlice, pSrcBox, + DstMipLevel, DstSlice, DstX, DstY, DstZ ); + + if( glCopyImageSubData ) + { + GLint SrcSliceY = (SrcTexDesc.Type == GL_TEXTURE_1D_ARRAY) ? SrcSlice : 0; + GLint SrcSliceZ = (SrcTexDesc.Type == GL_TEXTURE_2D_ARRAY) ? SrcSlice : 0; + GLint DstSliceY = (m_Desc.Type == GL_TEXTURE_1D_ARRAY) ? DstSlice : 0; + GLint DstSliceZ = (m_Desc.Type == GL_TEXTURE_2D_ARRAY) ? DstSlice : 0; + glCopyImageSubData( + pSrcTextureGL->GetGLHandle(), + pSrcTextureGL->GetBindTarget(), + SrcMipLevel, + pSrcBox->MinX, + pSrcBox->MinY + SrcSliceY, + pSrcBox->MinZ + SrcSliceZ, // Slice must be zero for 3D texture + GetGLHandle(), + GetBindTarget(), + DstMipLevel, + DstX, + DstY + DstSliceY, + DstZ + DstSliceZ, // Slice must be zero for 3D texture + pSrcBox->MaxX - pSrcBox->MinX, + pSrcBox->MaxY - pSrcBox->MinY, + pSrcBox->MaxZ - pSrcBox->MinZ ); + CHECK_GL_ERROR( "glCopyImageSubData() failed" ); + } + else + { + const auto &FmtAttribs = GetDevice()->GetTextureFormatInfoExt( m_Desc.Format ); + if( !FmtAttribs.ColorRenderable ) + { + LOG_ERROR_MESSAGE( "Unable to perform copy operation because ", FmtAttribs.Name, " is not color renderable format" ); + return; + } + + auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); + auto &FBOCache = pRenderDeviceGL->m_FBOCache; + auto &TexRegionRender = pRenderDeviceGL->m_TexRegionRender; + TexRegionRender.SetStates(pDeviceCtxGL); + + // Create temporary SRV for the entire source texture + TextureViewDesc SRVDesc; + SRVDesc.TextureType = SrcTexDesc.Type; + SRVDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE; + CorrectTextureViewDesc( SRVDesc ); + // Note: texture view allocates memory for the copy of the name + // If the name is empty, memory should not be allocated + TextureViewGLImpl SRV( GetDevice(), SRVDesc, pSrcTextureGL, + false, // Do NOT create texture view OpenGL object + true // The view, like default view, should not + // keep strong reference to the texture + ); + + for( Uint32 DepthSlice = 0; DepthSlice < pSrcBox->MaxZ - pSrcBox->MinZ; ++DepthSlice ) + { + // Create temporary RTV for the target subresource + TextureViewDesc RTVDesc; + RTVDesc.TextureType = m_Desc.Type; + RTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; + RTVDesc.FirstArraySlice = DepthSlice + DstSlice; + RTVDesc.MostDetailedMip = DstMipLevel; + RTVDesc.NumArraySlices = 1; + CorrectTextureViewDesc( RTVDesc ); + // Note: texture view allocates memory for the copy of the name + // If the name is empty, memory should not be allocated + TextureViewGLImpl RTV( GetDevice(), RTVDesc, this, + false, // Do NOT create texture view OpenGL object + true // The view, like default view, should not + // keep strong reference to the texture + ); + + ITextureView *pRTVs[] = { &RTV }; + pDeviceCtxGL->SetRenderTargets( _countof( pRTVs ), pRTVs, nullptr ); + + Viewport VP; + VP.TopLeftX = static_cast<float>( DstX ); + VP.TopLeftY = static_cast<float>( DstY ); + VP.Width = static_cast<float>(pSrcBox->MaxX - pSrcBox->MinX); + VP.Height = static_cast<float>(pSrcBox->MaxY - pSrcBox->MinY); + pDeviceCtxGL->SetViewports( 1, &VP, 0, 0 ); + + TexRegionRender.Render( pDeviceCtxGL, + &SRV, + SrcTexDesc.Type, + SrcTexDesc.Format, + static_cast<Int32>(pSrcBox->MinX) - static_cast<Int32>(DstX), + static_cast<Int32>(pSrcBox->MinY) - static_cast<Int32>(DstY), + SrcSlice + pSrcBox->MinZ + DepthSlice, + SrcMipLevel ); + } + + TexRegionRender.RestoreStates(pDeviceCtxGL); + } +} + + +void TextureBaseGL :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) +{ + TTextureBase::Map( pContext, MapType, MapFlags, pMappedData ); + //VERIFY( m_uiMapTarget == 0 && "Texture is already mapped"); + + //m_uiMapTarget = ( MapType == MAP_READ ) ? GL_COPY_READ_Texture : GL_COPY_WRITE_Texture; + //glBindTexture(m_uiMapTarget, m_GlTexture); + + //// !!!WARNING!!! GL_MAP_UNSYNCHRONIZED_BIT is not the same thing as MAP_FLAG_DO_NOT_WAIT. + //// If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize operations + //// on the Texture. This does not mean that map will fail if the Texture still in use. It is thus + //// what WRITE_NO_OVERWRITE does + + //GLbitfield Access = 0; + //switch(MapType) + //{ + // case MAP_READ: + // Access |= GL_MAP_READ_BIT; + // break; + + // case MAP_WRITE: + // Access |= GL_MAP_WRITE_BIT; + // break; + + // case MAP_READ_WRITE: + // Access |= GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + // break; + + // case MAP_WRITE_DISCARD: + // // If GL_MAP_INVALIDATE_Texture_BIT is specified, the entire contents of the Texture may + // // be discarded and considered invalid, regardless of the specified range. Any data + // // lying outside the mapped range of the Texture object becomes undefined,as does any + // // data within the range but not subsequently written by the application.This flag may + // // not be used with GL_MAP_READ_BIT. + // Access |= GL_MAP_INVALIDATE_Texture_BIT | GL_MAP_WRITE_BIT; + // break; + + // case MAP_WRITE_NO_OVERWRITE: + // // If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize + // // operations on the Texture. + // Access |= GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + // break; + + // default: UNEXPECTED("Unknown map type" ); + //} + + //pMappedData = glMapTextureRange(m_uiMapTarget, 0, m_Desc.uiSizeInBytes, Access); + //VERIFY( "Map failed" && pMappedData ); + //glBindTexture(m_uiMapTarget, 0); +} + +void TextureBaseGL::Unmap( IDeviceContext *pContext ) +{ + TTextureBase::Unmap(pContext); + + //glBindTexture(m_uiMapTarget, m_GlTexture); + //glUnmapTexture(m_uiMapTarget); + //glBindTexture(m_uiMapTarget, 0); + //m_uiMapTarget = 0; +} + +void TextureBaseGL::TextureMemoryBarrier( Uint32 RequiredBarriers, GLContextState &GLContextState ) +{ + const Uint32 TextureBarriers = + GL_TEXTURE_FETCH_BARRIER_BIT | + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | + GL_PIXEL_BUFFER_BARRIER_BIT | + GL_TEXTURE_UPDATE_BARRIER_BIT | + GL_FRAMEBUFFER_BARRIER_BIT; + VERIFY( (RequiredBarriers & TextureBarriers) != 0, "At least one texture memory barrier flag should be set" ); + VERIFY( (RequiredBarriers & ~TextureBarriers) == 0, "Inappropriate texture memory barrier flag" ); + + GLContextState.EnsureMemoryBarrier( RequiredBarriers, this ); +} + +void TextureBaseGL::SetDefaultGLParameters() +{ +#ifdef _DEBUG + GLint BoundTex; + GLint TextureBinding = 0; + switch( m_BindTarget ) + { + case GL_TEXTURE_1D: TextureBinding = GL_TEXTURE_BINDING_1D; break; + case GL_TEXTURE_1D_ARRAY: TextureBinding = GL_TEXTURE_BINDING_1D_ARRAY; break; + case GL_TEXTURE_2D: TextureBinding = GL_TEXTURE_BINDING_2D; break; + case GL_TEXTURE_2D_ARRAY: TextureBinding = GL_TEXTURE_BINDING_2D_ARRAY; break; + case GL_TEXTURE_2D_MULTISAMPLE: TextureBinding = GL_TEXTURE_BINDING_2D_MULTISAMPLE; break; + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: TextureBinding = GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; break; + case GL_TEXTURE_3D: TextureBinding = GL_TEXTURE_BINDING_3D; break; + default: UNEXPECTED("Unknown bind target"); + } + glGetIntegerv( TextureBinding, &BoundTex ); + CHECK_GL_ERROR( "Failed to set GL_TEXTURE_MIN_FILTER texture parameter" ); + VERIFY( BoundTex == m_GlTexture, "Current texture is not bound to GL context" ); +#endif + + if( m_BindTarget != GL_TEXTURE_2D_MULTISAMPLE && + m_BindTarget != GL_TEXTURE_2D_MULTISAMPLE_ARRAY ) + { + // Note that texture bound to image unit must be complete. + // That means that if an integer texture is being bound, its + // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, + // otherwise it will be incomplete + + // The default value of GL_TEXTURE_MIN_FILTER is GL_NEAREST_MIPMAP_LINEAR + // Reset it to GL_NEAREST to avoid incompletness issues with integer textures + glTexParameteri( m_BindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + CHECK_GL_ERROR( "Failed to set GL_TEXTURE_MIN_FILTER texture parameter" ); + + // The default value of GL_TEXTURE_MAG_FILTER is GL_LINEAR + glTexParameteri( m_BindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + CHECK_GL_ERROR( "Failed to set GL_TEXTURE_MAG_FILTER texture parameter" ); + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp new file mode 100644 index 00000000..10fbb630 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp @@ -0,0 +1,84 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "TextureViewGLImpl.h" +#include "RenderDeviceGLImpl.h" +#include "TextureBaseGL.h" +#include "DeviceContextGLImpl.h" + +namespace Diligent +{ + TextureViewGLImpl::TextureViewGLImpl( IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + TextureBaseGL* pTexture, + bool bCreateGLViewTex, + bool bIsDefaultView ) : + TTextureViewBase(pDevice, ViewDesc, pTexture, bIsDefaultView), + m_ViewTexGLHandle( bCreateGLViewTex ), + m_ViewTexBindTarget(0) + { + } + + TextureViewGLImpl::~TextureViewGLImpl() + { + } + + IMPLEMENT_QUERY_INTERFACE( TextureViewGLImpl, IID_TextureViewGL, TTextureViewBase ) + + const GLObjectWrappers::GLTextureObj& TextureViewGLImpl::GetHandle() + { + if( m_ViewTexGLHandle ) + return m_ViewTexGLHandle; + else + { + auto *pTexture = GetTexture(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); + return static_cast<TextureBaseGL*>(pTexture)->GetGLHandle(); + } + } + + GLenum TextureViewGLImpl::GetBindTarget() + { + if( m_ViewTexGLHandle ) + return m_ViewTexBindTarget; + else + { + auto *pTexture = GetTexture(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); + return static_cast<TextureBaseGL*>(pTexture)->GetBindTarget(); + } + } + + void TextureViewGLImpl::GenerateMips( IDeviceContext *pContext ) + { + auto pCtxGL = ValidatedCast<DeviceContextGLImpl>( pContext ); + auto &GLState = pCtxGL->GetContextState(); + auto BindTarget = GetBindTarget(); + GLState.BindTexture( -1, BindTarget, GetHandle() ); + glGenerateMipmap( BindTarget ); + CHECK_GL_ERROR( "Failed to generate mip maps" ); + GLState.BindTexture( -1, BindTarget, GLObjectWrappers::GLTextureObj(false) ); + } +} diff --git a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp new file mode 100644 index 00000000..4a3891b3 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp @@ -0,0 +1,220 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "VAOCache.h" +#include "RenderDeviceGLImpl.h" +#include "GLObjectWrapper.h" +#include "BufferGLImpl.h" +#include "GLTypeConversions.h" +#include "GLContextState.h" + +namespace Diligent +{ + +VAOCache::VAOCache() +{ + m_Cache.max_load_factor(0.5f); + m_VertexDescToKey.max_load_factor(0.5f); + m_BuffToKey.max_load_factor(0.5f); +} + +VAOCache::~VAOCache() +{ + VERIFY(m_Cache.empty(), "VAO cache is not empty. Are there any unreleased objects?"); + VERIFY(m_VertexDescToKey.empty(), "VertexDescToKey hash is not empty" ); + VERIFY(m_BuffToKey.empty(), "BuffToKey hash is not empty"); +} + +void VAOCache::OnDestroyBuffer(IBuffer *pBuffer) +{ + ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); + auto EqualRange = m_BuffToKey.equal_range(pBuffer); + for(auto It = EqualRange.first; It != EqualRange.second; ++It) + { + m_Cache.erase(It->second); + } + m_BuffToKey.erase(EqualRange.first, EqualRange.second); +} + +void VAOCache::OnDestroyVertexDesc(IVertexDescription *pVertexDesc) +{ + ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); + auto EqualRange = m_VertexDescToKey.equal_range(pVertexDesc); + for(auto It = EqualRange.first; It != EqualRange.second; ++It) + { + m_Cache.erase(It->second); + } + m_VertexDescToKey.erase(EqualRange.first, EqualRange.second); +} + +const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO( IVertexDescription &VertexDesc, + IBuffer *pIndexBuffer, + vector< VertexStreamInfo > &VertexStreams, + GLContextState &GLContextState ) +{ + // Lock the cache + ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); + + RefCntAutoPtr<IBuffer> spVertexBuffers[MaxBufferSlots]; + + // Get layout + const auto *LayoutElems = VertexDesc.GetDesc().LayoutElements; + auto NumElems = VertexDesc.GetDesc().NumElements; + const auto *TightStrides = VertexDesc.GetTightStrides(); + // Construct the key + VAOCacheKey Key = {0}; + Key.pVertexDesc = &VertexDesc; + Key.pIndexBuffer = pIndexBuffer; + + auto LayoutIt = LayoutElems; + for( size_t Elem = 0; Elem < NumElems; ++Elem, ++LayoutIt ) + { + auto BuffSlot = LayoutIt->BufferSlot; + if( BuffSlot >= VertexStreams.size() ) + { + UNEXPECTED( "Input layout requires more buffers than bound to the pipeline" ); + continue; + } + if( BuffSlot >= MaxBufferSlots ) + { + VERIFY( BuffSlot >= MaxBufferSlots, "Incorrect input slot" ); + continue; + } + auto &CurrStream = VertexStreams[BuffSlot]; + auto Stride = CurrStream.Stride ? CurrStream.Stride : TightStrides[BuffSlot]; + auto &spCurrBuf = spVertexBuffers[BuffSlot]; + auto &CurrStreamKey = Key.Streams[BuffSlot]; + if( !spCurrBuf ) + { + spCurrBuf = CurrStream.pBuffer; + VERIFY( spCurrBuf, "Buffer no longer exists" ); + + CHECK_DYNAMIC_TYPE( BufferGLImpl, spCurrBuf.RawPtr() ); + static_cast<BufferGLImpl*>(spCurrBuf.RawPtr())->BufferMemoryBarrier( + GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT,// Vertex data sourced from buffer objects after the barrier + // will reflect data written by shaders prior to the barrier. + // The set of buffer objects affected by this bit is derived + // from the GL_VERTEX_ARRAY_BUFFER_BINDING bindings + GLContextState); + + CurrStreamKey.pBuffer = spCurrBuf.RawPtr(); + CurrStreamKey.Stride = Stride; + CurrStreamKey.Offset = CurrStream.Offset; + } + else + { + VERIFY( spCurrBuf == CurrStream.pBuffer, "Buffer no longer exists" ); + VERIFY( CurrStreamKey.pBuffer == spCurrBuf.RawPtr(), "Unexpected buffer" ); + VERIFY( CurrStreamKey.Stride == Stride, "Unexpected buffer stride" ); + VERIFY( CurrStreamKey.Offset == CurrStream.Offset, "Unexpected buffer offset" ); + } + } + + if( pIndexBuffer ) + { + CHECK_DYNAMIC_TYPE( BufferGLImpl, pIndexBuffer ); + static_cast<BufferGLImpl*>(pIndexBuffer)->BufferMemoryBarrier( + GL_ELEMENT_ARRAY_BARRIER_BIT,// Vertex array indices sourced from buffer objects after the barrier + // will reflect data written by shaders prior to the barrier. + // The buffer objects affected by this bit are derived from the + // ELEMENT_ARRAY_BUFFER binding. + GLContextState); + } + + // Try to find VAO in the map + auto It = m_Cache.find(Key); + if( It != m_Cache.end() ) + { + return It->second; + } + else + { + // Create new VAO + GLObjectWrappers::GLVertexArrayObj NewVAO(true); + + // Initialize VAO + GLContextState.BindVAO( NewVAO ); + auto LayoutIt = LayoutElems; + for( size_t Elem = 0; Elem < NumElems; ++Elem, ++LayoutIt ) + { + auto BuffSlot = LayoutIt->BufferSlot; + if( BuffSlot >= VertexStreams.size() || BuffSlot >= MaxBufferSlots ) + { + UNEXPECTED( "Incorrect input buffer slot" ); + continue; + } + // Get buffer through the strong reference. Note that we are not + // using pointers stored in the key for safety + auto &CurrStream = VertexStreams[BuffSlot]; + auto Stride = CurrStream.Stride ? CurrStream.Stride : TightStrides[BuffSlot]; + auto &spBuff = spVertexBuffers[BuffSlot]; + VERIFY( spBuff, "Vertex buffer is null" ); + const BufferGLImpl *pBufferOGL = static_cast<const BufferGLImpl*>( spBuff.RawPtr() ); + + glBindBuffer(GL_ARRAY_BUFFER, pBufferOGL->m_GlBuffer); + GLvoid* DataStartOffset = reinterpret_cast<GLvoid*>( static_cast<size_t>( CurrStream.Offset + LayoutIt->RelativeOffset ) ); + auto GlType = TypeToGLType(LayoutIt->ValueType); + if( !LayoutIt->IsNormalized && + (LayoutIt->ValueType == VT_INT8 || + LayoutIt->ValueType == VT_INT16 || + LayoutIt->ValueType == VT_INT32 || + LayoutIt->ValueType == VT_UINT8 || + LayoutIt->ValueType == VT_UINT16|| + LayoutIt->ValueType == VT_UINT32 ) ) + glVertexAttribIPointer(LayoutIt->InputIndex, LayoutIt->NumComponents, GlType, Stride, DataStartOffset ); + else + glVertexAttribPointer(LayoutIt->InputIndex, LayoutIt->NumComponents, GlType, LayoutIt->IsNormalized, Stride, DataStartOffset ); + + if( LayoutIt->Frequency == LayoutElement::FREQUENCY_PER_INSTANCE ) + { + // If divisor is zero, then the attribute acts like normal, being indexed by the array or index + // buffer. If divisor is non-zero, then the current instance is divided by this divisor, and + // the result of that is used to access the attribute array. + glVertexAttribDivisor(LayoutIt->InputIndex, LayoutIt->InstanceDataStepRate); + } + glEnableVertexAttribArray(LayoutIt->InputIndex); + } + if( pIndexBuffer ) + { + const BufferGLImpl *pIndBufferOGL = static_cast<const BufferGLImpl*>( pIndexBuffer ); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndBufferOGL->m_GlBuffer); + } + + auto NewElems = m_Cache.emplace( make_pair(Key, std::move(NewVAO)) ); + // New element must be actually inserted + VERIFY( NewElems.second, "New element was not inserted into the cache" ); + m_VertexDescToKey.insert( make_pair(Key.pVertexDesc, Key) ); + for(int iStream = 0; iStream < _countof(Key.Streams); ++iStream) + { + auto *pCurrBuff = Key.Streams[iStream].pBuffer; + if( pCurrBuff ) + m_BuffToKey.insert( make_pair(pCurrBuff, Key) ); + } + + return NewElems.first->second; + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/VertexDescGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/VertexDescGLImpl.cpp new file mode 100644 index 00000000..0b2b6b50 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/VertexDescGLImpl.cpp @@ -0,0 +1,45 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "VertexDescGLImpl.h" +#include "RenderDeviceGLImpl.h" + +namespace Diligent +{ + +VertexDescGLImpl::VertexDescGLImpl( RenderDeviceGLImpl *pDeviceGL, const LayoutDesc &LayoutDesc, bool bIsDeviceInternal ) : + TVertexDescriptionBase(pDeviceGL, LayoutDesc) +{ + +} + +VertexDescGLImpl::~VertexDescGLImpl() +{ + static_cast<RenderDeviceGLImpl*>( GetDevice() )->m_VAOCache.OnDestroyVertexDesc(this); +} + +IMPLEMENT_QUERY_INTERFACE( VertexDescGLImpl, IID_VertexDescriptionGL, TVertexDescriptionBase ) + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/pch.cpp b/Graphics/GraphicsEngineOpenGL/src/pch.cpp new file mode 100644 index 00000000..0bfe300d --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/pch.cpp @@ -0,0 +1,31 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// stdafx.cpp : source file that includes just the standard includes +// GraphicsEngineOpenGL.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "pch.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/Graphics/GraphicsTools/build/Windows/EngineRoot.props b/Graphics/GraphicsTools/build/Windows/EngineRoot.props new file mode 100644 index 00000000..6e4b958b --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows/EngineRoot.props @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..</GraphicsRoot> + </PropertyGroup> + <PropertyGroup /> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools-Debug.vgdbsettings b/Graphics/GraphicsTools/build/Windows/GraphicsTools-Debug.vgdbsettings new file mode 100644 index 00000000..3f5b24b1 --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows/GraphicsTools-Debug.vgdbsettings @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<VisualGDBProjectSettings2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <ConfigurationName>Debug</ConfigurationName> + <Project xsi:type="com.visualgdb.project.android"> + <CustomSourceDirectories> + <Directories /> + <PathStyle>MinGWWindowsSlash</PathStyle> + </CustomSourceDirectories> + <AndroidProjectPath>$(ProjectDir)</AndroidProjectPath> + </Project> + <Build xsi:type="com.visualgdb.build.android"> + <AndroidPlatform>android-19</AndroidPlatform> + <IsDebugConfiguration>true</IsDebugConfiguration> + <JNIOnlyBuild>true</JNIOnlyBuild> + <AdditionalDirectoriesToDeleteOnClean>bin;obj</AdditionalDirectoriesToDeleteOnClean> + <DeleteANTFilesOnClean>false</DeleteANTFilesOnClean> + <DoNotEditAndroidManifest>false</DoNotEditAndroidManifest> + <CustomActions /> + </Build> + <Debug xsi:type="com.visualgdb.debug.android"> + <AdditionalStartupCommands /> + <AdditionalGDBSettings> + <FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications> + <ForceSingleThreadedMode>false</ForceSingleThreadedMode> + <PendingBreakpointsSupported>true</PendingBreakpointsSupported> + <DisableChildRanges>false</DisableChildRanges> + <UseAppleExtensions>false</UseAppleExtensions> + <CanAcceptCommandsWhileRunning>false</CanAcceptCommandsWhileRunning> + <MakeLogFile>false</MakeLogFile> + <IgnoreModuleEventsWhileStepping>true</IgnoreModuleEventsWhileStepping> + <UseRelativePathsOnly>false</UseRelativePathsOnly> + <ExitAction>KillApp</ExitAction> + <Features> + <DisableAutoDetection>false</DisableAutoDetection> + <UseFrameParameter>false</UseFrameParameter> + <SimpleValuesFlagSupported>false</SimpleValuesFlagSupported> + <ListLocalsSupported>false</ListLocalsSupported> + <ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable> + <ThreadInfoSupported>false</ThreadInfoSupported> + <PendingBreakpointsSupported>false</PendingBreakpointsSupported> + <SupportTargetCommand>false</SupportTargetCommand> + </Features> + <DisableDisassembly>false</DisableDisassembly> + <ExamineMemoryWithXCommand>false</ExamineMemoryWithXCommand> + <StepIntoNewInstanceEntry>main</StepIntoNewInstanceEntry> + <ExamineRegistersInRawFormat>true</ExamineRegistersInRawFormat> + </AdditionalGDBSettings> + <LaunchGDBSettings xsi:type="GDBLaunchParametersAndroid" /> + <GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC> + <UseDefaultInstallDir>false</UseDefaultInstallDir> + <RemotePort>5039</RemotePort> + <LocalPort>5039</LocalPort> + <GDBServerStartupTimeout>10000</GDBServerStartupTimeout> + <AdditionalGDBServerStartupDelay>0</AdditionalGDBServerStartupDelay> + <DoubleSlashWorkaround>false</DoubleSlashWorkaround> + <AlreadyRunningDecision>Ask</AlreadyRunningDecision> + <ShowLogCat>true</ShowLogCat> + <EnableThreadNameWatcher>true</EnableThreadNameWatcher> + </Debug> + <CustomBuild> + <PreBuildActions /> + <PostBuildActions /> + <PreCleanActions /> + <PostCleanActions /> + </CustomBuild> + <CustomDebug> + <PreDebugActions /> + <PostDebugActions /> + <BreakMode>Default</BreakMode> + </CustomDebug> + <CustomShortcuts> + <Shortcuts /> + <ShowMessageAfterExecuting>true</ShowMessageAfterExecuting> + </CustomShortcuts> + <UserDefinedVariables /> +</VisualGDBProjectSettings2>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools-Release.vgdbsettings b/Graphics/GraphicsTools/build/Windows/GraphicsTools-Release.vgdbsettings new file mode 100644 index 00000000..669691f2 --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows/GraphicsTools-Release.vgdbsettings @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<VisualGDBProjectSettings2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <ConfigurationName>Release</ConfigurationName> + <Project xsi:type="com.visualgdb.project.android"> + <CustomSourceDirectories> + <Directories /> + <PathStyle>MinGWWindowsSlash</PathStyle> + </CustomSourceDirectories> + <AndroidProjectPath>$(ProjectDir)</AndroidProjectPath> + </Project> + <Build xsi:type="com.visualgdb.build.android"> + <AndroidPlatform>android-19</AndroidPlatform> + <IsDebugConfiguration>false</IsDebugConfiguration> + <JNIOnlyBuild>true</JNIOnlyBuild> + <AdditionalDirectoriesToDeleteOnClean>bin;obj</AdditionalDirectoriesToDeleteOnClean> + <DeleteANTFilesOnClean>false</DeleteANTFilesOnClean> + <DoNotEditAndroidManifest>false</DoNotEditAndroidManifest> + <CustomActions /> + </Build> + <Debug xsi:type="com.visualgdb.debug.android"> + <AdditionalStartupCommands /> + <AdditionalGDBSettings> + <FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications> + <ForceSingleThreadedMode>false</ForceSingleThreadedMode> + <PendingBreakpointsSupported>true</PendingBreakpointsSupported> + <DisableChildRanges>false</DisableChildRanges> + <UseAppleExtensions>false</UseAppleExtensions> + <CanAcceptCommandsWhileRunning>false</CanAcceptCommandsWhileRunning> + <MakeLogFile>false</MakeLogFile> + <IgnoreModuleEventsWhileStepping>true</IgnoreModuleEventsWhileStepping> + <UseRelativePathsOnly>false</UseRelativePathsOnly> + <ExitAction>KillApp</ExitAction> + <Features> + <DisableAutoDetection>false</DisableAutoDetection> + <UseFrameParameter>false</UseFrameParameter> + <SimpleValuesFlagSupported>false</SimpleValuesFlagSupported> + <ListLocalsSupported>false</ListLocalsSupported> + <ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable> + <ThreadInfoSupported>false</ThreadInfoSupported> + <PendingBreakpointsSupported>false</PendingBreakpointsSupported> + <SupportTargetCommand>false</SupportTargetCommand> + </Features> + <DisableDisassembly>false</DisableDisassembly> + <ExamineMemoryWithXCommand>false</ExamineMemoryWithXCommand> + <StepIntoNewInstanceEntry>main</StepIntoNewInstanceEntry> + <ExamineRegistersInRawFormat>true</ExamineRegistersInRawFormat> + </AdditionalGDBSettings> + <LaunchGDBSettings xsi:type="GDBLaunchParametersAndroid" /> + <GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC> + <UseDefaultInstallDir>false</UseDefaultInstallDir> + <RemotePort>5039</RemotePort> + <LocalPort>5039</LocalPort> + <GDBServerStartupTimeout>10000</GDBServerStartupTimeout> + <AdditionalGDBServerStartupDelay>0</AdditionalGDBServerStartupDelay> + <DoubleSlashWorkaround>false</DoubleSlashWorkaround> + <AlreadyRunningDecision>Ask</AlreadyRunningDecision> + <ShowLogCat>true</ShowLogCat> + <EnableThreadNameWatcher>true</EnableThreadNameWatcher> + </Debug> + <CustomBuild> + <PreBuildActions /> + <PostBuildActions /> + <PreCleanActions /> + <PostCleanActions /> + </CustomBuild> + <CustomDebug> + <PreDebugActions /> + <PostDebugActions /> + <BreakMode>Default</BreakMode> + </CustomDebug> + <CustomShortcuts> + <Shortcuts /> + <ShowMessageAfterExecuting>true</ShowMessageAfterExecuting> + </CustomShortcuts> + <UserDefinedVariables /> +</VisualGDBProjectSettings2>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools.props b/Graphics/GraphicsTools/build/Windows/GraphicsTools.props new file mode 100644 index 00000000..22851e71 --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows/GraphicsTools.props @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsTools\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\TextureLoader\interface;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup /> + <ItemGroup /> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj b/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj new file mode 100644 index 00000000..c90a589b --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj @@ -0,0 +1,181 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C6014499-0CF2-43EC-A773-A4E354FB2D74}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>GraphicsTools</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + <Import Project="..\WindowsStore\GraphicsTools.Shared\GraphicsTools.Shared.vcxitems" Label="Shared" Condition="Exists('..\WindowsStore\GraphicsTools.Shared\GraphicsTools.Shared.vcxitems')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="EngineRoot.props" /> + <Import Project="GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="..\..\..\..\Shared\build\Windows\Android32d.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="..\..\..\..\Shared\build\Windows\Android32r.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <Text Include="ReadMe.txt" /> + </ItemGroup> + <ItemGroup> + <None Include="jni\Android.mk" /> + <None Include="jni\Application.mk" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\BasicShaderSourceStreamFactory.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\GraphicsUtilities.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj.filters b/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj.filters new file mode 100644 index 00000000..89d44e9e --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj.filters @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="android_src"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="jni"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <Text Include="ReadMe.txt" /> + </ItemGroup> + <ItemGroup> + <None Include="jni\Android.mk"> + <Filter>jni</Filter> + </None> + <None Include="jni\Application.mk"> + <Filter>jni</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\BasicShaderSourceStreamFactory.cpp"> + <Filter>android_src</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GraphicsUtilities.cpp"> + <Filter>android_src</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/jni/Android.mk b/Graphics/GraphicsTools/build/Windows/jni/Android.mk new file mode 100644 index 00000000..2b02dd54 --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows/jni/Android.mk @@ -0,0 +1,25 @@ +# Android NDK project makefile autogenerated by Premake + +# Preamble +DEPENDENCY_PATH := $(call my-dir) +LOCAL_PATH := $(abspath $(DEPENDENCY_PATH)) +include $(CLEAR_VARS) + + +# Project configuration +LOCAL_MODULE := GraphicsTools +LOCAL_CFLAGS := -std=c++11 +LOCAL_CPP_FEATURES := exceptions +LOCAL_STATIC_LIBRARIES += + +# Include paths +PROJECT_ROOT := $(LOCAL_PATH)/../../.. +GRAPHICS_ROOT := $(PROJECT_ROOT)/.. +SOLUTION_ROOT := $(GRAPHICS_ROOT)/.. +LOCAL_C_INCLUDES := $(PROJECT_ROOT)/include $(SOLUTION_ROOT)/Common/include $(SOLUTION_ROOT)/Common/interface $(SOLUTION_ROOT)/Platforms/interface $(GRAPHICS_ROOT)/GraphicsEngine/interface $(GRAPHICS_ROOT)/GraphicsTools/include $(GRAPHICS_ROOT)/TextureLoader/interface + +# Source files +#VisualGDBAndroid: AutoUpdateSourcesInNextLine +LOCAL_SRC_FILES := ../../../src/BasicShaderSourceStreamFactory.cpp ../../../src/GraphicsUtilities.cpp + +include $(BUILD_STATIC_LIBRARY) diff --git a/Graphics/GraphicsTools/build/Windows/jni/Application.mk b/Graphics/GraphicsTools/build/Windows/jni/Application.mk new file mode 100644 index 00000000..063ff721 --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows/jni/Application.mk @@ -0,0 +1,7 @@ +# Generated by VisualGDB + +DEPENDENCY_PATH := $(call my-dir) +LOCAL_PATH := $(abspath $(DEPENDENCY_PATH)) +include $(LOCAL_PATH)/../../../../../Common/make/AppCommon.mk + +APP_MODULES := GraphicsTools
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/EngineRoot.props b/Graphics/GraphicsTools/build/WindowsStore/EngineRoot.props new file mode 100644 index 00000000..fcb891c0 --- /dev/null +++ b/Graphics/GraphicsTools/build/WindowsStore/EngineRoot.props @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..\..</GraphicsRoot> + </PropertyGroup> + <PropertyGroup /> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems new file mode 100644 index 00000000..6a1aa429 --- /dev/null +++ b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <ItemsProjectGuid>{3bb4f2ac-1d2f-4af6-b9cc-bdc17bb8bc39}</ItemsProjectGuid> + <ItemsRootNamespace>GraphicsTools</ItemsRootNamespace> + <ItemsProjectName>GraphicsTools.Shared</ItemsProjectName> + <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectCapability Include="SourceItemsFromImports" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BasicShaderSourceStreamFactory.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\GraphicsUtilities.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderMacroHelper.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BasicShaderSourceStreamFactory.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\GraphicsUtilities.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems.filters b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems.filters new file mode 100644 index 00000000..ed522894 --- /dev/null +++ b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems.filters @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="include"> + <UniqueIdentifier>{610cb4a4-ad9a-42e0-936c-239055f0caa6}</UniqueIdentifier> + </Filter> + <Filter Include="src"> + <UniqueIdentifier>{2fa69c92-b6b7-4e73-9ccd-49a715515cc8}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BasicShaderSourceStreamFactory.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\GraphicsUtilities.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderMacroHelper.h"> + <Filter>include</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BasicShaderSourceStreamFactory.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\GraphicsUtilities.cpp"> + <Filter>src</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj new file mode 100644 index 00000000..85152c29 --- /dev/null +++ b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj @@ -0,0 +1,205 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{dac331f3-c5a2-4568-8714-9213c3487a49}</ProjectGuid> + <RootNamespace>GraphicsTools</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <AppContainerApplication>true</AppContainerApplication> + <ApplicationType>Windows Store</ApplicationType> + <ApplicationTypeRevision>8.1</ApplicationTypeRevision> + <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="..\GraphicsTools.Shared\GraphicsTools.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj.filters b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj.filters new file mode 100644 index 00000000..a7761ab0 --- /dev/null +++ b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj.filters @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + </ItemGroup> +</Project> diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj new file mode 100644 index 00000000..e99bf6b4 --- /dev/null +++ b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{2f340c0e-43b2-471f-b4f3-7cdce69f6e1f}</ProjectGuid> + <RootNamespace>GraphicsTools</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <AppContainerApplication>true</AppContainerApplication> + <ApplicationType>Windows Phone</ApplicationType> + <ApplicationTypeRevision>8.1</ApplicationTypeRevision> + <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120_wp81</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="..\GraphicsTools.Shared\GraphicsTools.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> + <Import Project="..\EngineRoot.props" /> + <Import Project="..\..\Windows\GraphicsTools.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj.filters b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj.filters new file mode 100644 index 00000000..a7761ab0 --- /dev/null +++ b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj.filters @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + </ItemGroup> +</Project> diff --git a/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h b/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h new file mode 100644 index 00000000..76adc056 --- /dev/null +++ b/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h @@ -0,0 +1,41 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BasicFileStream.h" +#include "Shader.h" + +namespace Diligent +{ + class BasicShaderSourceStreamFactory : public IShaderSourceInputStreamFactory + { + public: + BasicShaderSourceStreamFactory( const Char *SearchDirectories = nullptr ); + + virtual void CreateInputStream( const Diligent::Char *Name, IFileStream **ppStream )override; + + private: + std::vector<Diligent::String> m_SearchDirectories; + }; +} diff --git a/Graphics/GraphicsTools/include/GraphicsUtilities.h b/Graphics/GraphicsTools/include/GraphicsUtilities.h new file mode 100644 index 00000000..78002d01 --- /dev/null +++ b/Graphics/GraphicsTools/include/GraphicsUtilities.h @@ -0,0 +1,201 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Defines graphics engine utilities + +#include "GraphicsTypes.h" +#include "Shader.h" +#include "Texture.h" +#include "Buffer.h" +#include "RenderDevice.h" + +namespace Diligent +{ + +/// Template structure to convert VALUE_TYPE enumeration into C-type +template<VALUE_TYPE ValType> +struct VALUE_TYPE2CType +{}; + +/// VALUE_TYPE2CType<> template specialization for 8-bit integer value type. + +/// Usage example: +/// +/// VALUE_TYPE2CType<VT_INT8>::CType MyInt8Var; +template<>struct VALUE_TYPE2CType<VT_INT8> { typedef Int8 CType; }; + +/// VALUE_TYPE2CType<> template specialization for 16-bit integer value type. + +/// Usage example: +/// +/// VALUE_TYPE2CType<VT_INT16>::CType MyInt16Var; +template<>struct VALUE_TYPE2CType<VT_INT16> { typedef Int16 CType; }; + +/// VALUE_TYPE2CType<> template specialization for 32-bit integer value type. + +/// Usage example: +/// +/// VALUE_TYPE2CType<VT_INT32>::CType MyInt32Var; +template<>struct VALUE_TYPE2CType<VT_INT32> { typedef Int32 CType; }; + +/// VALUE_TYPE2CType<> template specialization for 8-bit unsigned-integer value type. + +/// Usage example: +/// +/// VALUE_TYPE2CType<VT_UINT8>::CType MyUint8Var; +template<>struct VALUE_TYPE2CType<VT_UINT8> { typedef Uint8 CType; }; + +/// VALUE_TYPE2CType<> template specialization for 16-bit unsigned-integer value type. + +/// Usage example: +/// +/// VALUE_TYPE2CType<VT_UINT16>::CType MyUint16Var; +template<>struct VALUE_TYPE2CType<VT_UINT16>{ typedef Uint16 CType; }; + +/// VALUE_TYPE2CType<> template specialization for 32-bit unsigned-integer value type. + +/// Usage example: +/// +/// VALUE_TYPE2CType<VT_UINT32>::CType MyUint32Var; +template<>struct VALUE_TYPE2CType<VT_UINT32>{ typedef Uint32 CType; }; + +/// VALUE_TYPE2CType<> template specialization for half-precision 16-bit floating-point value type. + +/// Usage example: +/// +/// VALUE_TYPE2CType<VT_FLOAT16>::CType MyFloat16Var; +/// +/// \note 16-bit floating-point values have no corresponding C++ type and are translated to Uint16 +template<>struct VALUE_TYPE2CType<VT_FLOAT16>{ typedef Uint16 CType; }; + +/// VALUE_TYPE2CType<> template specialization for full-precision 32-bit floating-point value type. + +/// Usage example: +/// +/// VALUE_TYPE2CType<VT_FLOAT32>::CType MyFloat32Var; +template<>struct VALUE_TYPE2CType<VT_FLOAT32>{ typedef Float32 CType; }; + + +/// Returns the size of the specified value type +Uint32 GetValueSize( VALUE_TYPE Val ); + +/// Returns the string representing the specified value type +const Char* GetValueTypeString( VALUE_TYPE Val ); + +/// Returns invariant texture format attributes, see TextureFormatAttribs for details. + +/// \param [in] Format - Texture format which attributes are requested for. +/// \return Constant reference to the TextureFormatAttribs structure containing +/// format attributes. +const TextureFormatAttribs& GetTextureFormatAttribs(TEXTURE_FORMAT Format); + + +/// Returns the literal name of a texture view type. For instance, +/// for a shader resource view, "TEXTURE_VIEW_SHADER_RESOURCE" will be returned. + +/// \param [in] ViewType - Texture view type. +/// \return Literal name of the texture view type. +const Char *GetTexViewTypeLiteralName(TEXTURE_VIEW_TYPE ViewType); + +/// Returns the literal name of a buffer view type. For instance, +/// for an unordered access view, "BUFFER_VIEW_UNORDERED_ACCESS" will be returned. + +/// \param [in] ViewType - Buffer view type. +/// \return Literal name of the buffer view type. +const Char *GetBufferViewTypeLiteralName(BUFFER_VIEW_TYPE ViewType); + +/// Returns the literal name of a shader type. For instance, +/// for a pixel shader, "SHADER_TYPE_PIXEL" will be returned. + +/// \param [in] ShaderType - Shader type. +/// \return Literal name of the shader type. +const Char *GetShaderTypeLiteralName(SHADER_TYPE ShaderType); + +/// Overloaded function that returns the literal name of a texture view type. +/// see GetTexViewTypeLiteralName(). +inline const Char* GetViewTypeLiteralName(TEXTURE_VIEW_TYPE TexViewType) +{ + return GetTexViewTypeLiteralName( TexViewType ); +} + +/// Overloaded function that returns the literal name of a buffer view type. +/// see GetBufferViewTypeLiteralName(). +inline const Char* GetViewTypeLiteralName(BUFFER_VIEW_TYPE BuffViewType) +{ + return GetBufferViewTypeLiteralName( BuffViewType ); +} + +/// Returns the string containing the usage +const Char* GetUsageString(USAGE Usage); + +/// Returns the string containing the texture type +const Char* GetTextureTypeString( TEXTURE_TYPE TexType ); + +/// Returns the string containing the bind flags +String GetBindFlagsString( Uint32 BindFlags ); + +/// Returns the string containing the CPU access flags +String GetCPUAccessFlagsString( Uint32 CpuAccessFlags ); + +/// Returns the string containing the texture description +String GetTextureDescString(const TextureDesc &Desc); + +/// Returns the string containing the buffer description +String GetBufferDescString(const BufferDesc &Desc); + + +/// Helper template function that converts object description into a string +template<typename TObjectDescType> +String GetObjectDescString( const TObjectDescType& ) +{ + return ""; +} + +/// Template specialization for texture description +template<> +inline String GetObjectDescString( const TextureDesc& TexDesc ) +{ + String Str( "Tex desc: " ); + Str += GetTextureDescString( TexDesc ); + return Str; +} + +/// Template specialization for buffer description +template<> +inline String GetObjectDescString( const BufferDesc& BuffDesc ) +{ + String Str( "Buff desc: " ); + Str += GetBufferDescString( BuffDesc ); + return Str; +} + +Uint32 ComputeMipLevelsCount( Uint32 Width ); +Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height ); +Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height, Uint32 Depth ); + +void CreateUniformBuffer( IRenderDevice *pDevice, Uint32 Size, IBuffer **ppBuffer, USAGE Usage = USAGE_DYNAMIC, Uint32 BindFlag = BIND_UNIFORM_BUFFER, Uint32 CPUAccessFlags = CPU_ACCESS_WRITE ); + +} diff --git a/Graphics/GraphicsTools/include/ShaderMacroHelper.h b/Graphics/GraphicsTools/include/ShaderMacroHelper.h new file mode 100644 index 00000000..bcfc3e52 --- /dev/null +++ b/Graphics/GraphicsTools/include/ShaderMacroHelper.h @@ -0,0 +1,122 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +//-------------------------------------------------------------------------------------- +// Copyright 2013 Intel Corporation +// All Rights Reserved +// +// Permission is granted to use, copy, distribute and prepare derivative works of this +// software for any purpose and without fee, provided, that the above copyright notice +// and this statement appear in all copies. Intel makes no representations about the +// suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS." +// INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, AND ALL LIABILITY, +// INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, FOR THE USE OF THIS SOFTWARE, +// INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY RIGHTS, AND INCLUDING THE +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Intel does not +// assume any responsibility for any errors which may appear in this software nor any +// responsibility to update it. +//-------------------------------------------------------------------------------------- + +#include <set> +#include <vector> +#include <sstream> +#include <iomanip> +#include "BasicTypes.h" +#include "DebugUtilities.h" +#include "Shader.h" + +namespace Diligent +{ + +class ShaderMacroHelper +{ +public: + ShaderMacroHelper() : m_bIsFinalized(false) {} + + template<typename DefintionType> + void AddShaderMacro( const Diligent::Char* Name, DefintionType Definition ) + { + assert( !m_bIsFinalized ); + std::ostringstream ss; + ss << Definition; + AddShaderMacro<const Diligent::Char*>( Name, ss.str().c_str() ); + } + + void Finalize() + { + ShaderMacro LastMacro = {NULL, NULL}; + m_Macros.push_back(LastMacro); + m_bIsFinalized = true; + } + + operator const ShaderMacro* () + { + assert( !m_Macros.size() || m_bIsFinalized ); + if( m_Macros.size() && !m_bIsFinalized ) + Finalize(); + return m_Macros.size() ? &m_Macros[0] : NULL; + } + +private: + + std::vector< ShaderMacro > m_Macros; + std::set< std::string > m_DefinitionsPull; + bool m_bIsFinalized; +}; + +template<> +inline void ShaderMacroHelper::AddShaderMacro( const Diligent::Char* Name, const Diligent::Char* Definition ) +{ + VERIFY_EXPR( !m_bIsFinalized ); + ShaderMacro NewMacro = + { + Name, + m_DefinitionsPull.insert(Definition).first->c_str() + }; + m_Macros.push_back(NewMacro); +} + +template<> +inline void ShaderMacroHelper::AddShaderMacro( const Diligent::Char* Name, bool Definition ) +{ + assert( !m_bIsFinalized ); + AddShaderMacro( Name, Definition ? "1" : "0"); +} + +template<> +inline void ShaderMacroHelper::AddShaderMacro( const Diligent::Char* Name, float Definition ) +{ + assert( !m_bIsFinalized ); + std::ostringstream ss; + + // Make sure that when floating point represents integer, it is still + // written as float: 1024.0, but not 1024. This is essnetial to + // avoid type conversion issues in GLES. + if( Definition == static_cast<float>(static_cast<int>(Definition)) ) + ss << std::fixed << std::setprecision( 1 ); + + ss << Definition; + AddShaderMacro<const Diligent::Char*>( Name, ss.str().c_str() ); +} + +} diff --git a/Graphics/GraphicsTools/include/pch.h b/Graphics/GraphicsTools/include/pch.h new file mode 100644 index 00000000..b2893486 --- /dev/null +++ b/Graphics/GraphicsTools/include/pch.h @@ -0,0 +1,26 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + + diff --git a/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp b/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp new file mode 100644 index 00000000..fa69c7c1 --- /dev/null +++ b/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp @@ -0,0 +1,87 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "BasicShaderSourceStreamFactory.h" +#include "RefCntAutoPtr.h" + +namespace Diligent +{ + BasicShaderSourceStreamFactory::BasicShaderSourceStreamFactory( const Char *SearchDirectories ) + { + while( SearchDirectories ) + { + const char* Semicolon = strchr( SearchDirectories, ';' ); + String SearchPath; + if( Semicolon == nullptr ) + { + SearchPath = SearchDirectories; + SearchDirectories = nullptr; + } + else + { + SearchPath = String( SearchDirectories, Semicolon ); + SearchDirectories = Semicolon + 1; + } + + if( SearchPath.length() > 0 ) + { + if( SearchPath.back() != '\\' && SearchPath.back() != '/' ) + SearchPath.push_back( '\\' ); + m_SearchDirectories.push_back( SearchPath ); + } + } + m_SearchDirectories.push_back( "" ); + } + + void BasicShaderSourceStreamFactory::CreateInputStream( const Diligent::Char *Name, IFileStream **ppStream ) + { + bool bFileCreated = false; + Diligent::RefCntAutoPtr<BasicFileStream> pBasicFileStream; + for( const auto &SearchDir : m_SearchDirectories ) + { + String FullPath = SearchDir + ( (Name[0] == '\\' || Name[0] == '/') ? Name + 1 : Name); + if( !FileSystem::FileExists( FullPath.c_str() ) ) + continue; + pBasicFileStream = new BasicFileStream( FullPath.c_str(), EFileAccessMode::Read ); + if( pBasicFileStream->IsValid() ) + { + bFileCreated = true; + break; + } + else + { + pBasicFileStream.Release(); + } + } + if( bFileCreated ) + { + pBasicFileStream->QueryInterface( IID_FileStream, reinterpret_cast<IObject**>(ppStream) ); + } + else + { + *ppStream = nullptr; + LOG_ERROR_AND_THROW( "Failed to create input stream for source file ", Name ) + } + } +}
\ No newline at end of file diff --git a/Graphics/GraphicsTools/src/GraphicsUtilities.cpp b/Graphics/GraphicsTools/src/GraphicsUtilities.cpp new file mode 100644 index 00000000..05cc0a3a --- /dev/null +++ b/Graphics/GraphicsTools/src/GraphicsUtilities.cpp @@ -0,0 +1,621 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "GraphicsUtilities.h" +#include "DebugUtilities.h" +#include <algorithm> + +namespace Diligent +{ + +Uint32 GetValueSize( VALUE_TYPE Val ) +{ + static Uint32 Sizes[VT_NUM_TYPES] = {}; + static bool bIsInit = false; + // Note that this implementation is thread-safe + // Even if two threads try to call the function at the same time, + // the worst thing that might happen is that the array will be + // initialized multiple times. But the result will always be correct + if( !bIsInit ) + { + Sizes[VT_UNDEFINED] = 0; +#define INIT_VALUE_SIZE( ValType ) Sizes[ValType] = sizeof(VALUE_TYPE2CType<ValType>::CType) + INIT_VALUE_SIZE( VT_INT8 ); + INIT_VALUE_SIZE( VT_INT16 ); + INIT_VALUE_SIZE( VT_INT32 ); + INIT_VALUE_SIZE( VT_UINT8 ); + INIT_VALUE_SIZE( VT_UINT16 ); + INIT_VALUE_SIZE( VT_UINT32 ); + INIT_VALUE_SIZE( VT_FLOAT16 ); + INIT_VALUE_SIZE( VT_FLOAT32 ); +#undef INIT_VALUE_SIZE + static_assert(VT_NUM_TYPES == VT_FLOAT32 + 1, "Not all value type sizes initialized."); + bIsInit = true; + } + + if( Val > VT_UNDEFINED && Val < VT_NUM_TYPES ) + { + return Sizes[Val]; + } + else + { + UNEXPECTED( "Incorrect value type (", Val, ")" ) + return 0; + } +} + +const Char* GetValueTypeString( VALUE_TYPE Val ) +{ + static const Char* ValueTypeStrings[VT_NUM_TYPES] = {}; + static bool bIsInit = false; + if( !bIsInit ) + { +#define INIT_VALUE_TYPE_STR( ValType ) ValueTypeStrings[ValType] = #ValType + INIT_VALUE_TYPE_STR( VT_UNDEFINED ); + INIT_VALUE_TYPE_STR( VT_INT8 ); + INIT_VALUE_TYPE_STR( VT_INT16 ); + INIT_VALUE_TYPE_STR( VT_INT32 ); + INIT_VALUE_TYPE_STR( VT_UINT8 ); + INIT_VALUE_TYPE_STR( VT_UINT16 ); + INIT_VALUE_TYPE_STR( VT_UINT32 ); + INIT_VALUE_TYPE_STR( VT_FLOAT16 ); + INIT_VALUE_TYPE_STR( VT_FLOAT32 ); +#undef INIT_VALUE_TYPE_STR + static_assert(VT_NUM_TYPES == VT_FLOAT32 + 1, "Not all value type strings initialized."); + bIsInit = true; + } + + if( Val >= VT_UNDEFINED && Val < VT_NUM_TYPES ) + { + return ValueTypeStrings[Val]; + } + else + { + UNEXPECTED( "Incorrect value type (", Val, ")" ) + return "unknown value type"; + } +} + +const TextureFormatAttribs& GetTextureFormatAttribs( TEXTURE_FORMAT Format ) +{ + static TextureFormatAttribs FmtAttribs[TEX_FORMAT_NUM_FORMATS] = {}; + static bool bIsInit = false; + // Note that this implementation is thread-safe + // Even if two threads try to call the function at the same time, + // the worst thing that might happen is that the array will be + // initialized multiple times. But the result will always be correct. + if( !bIsInit ) + { +#define INIT_TEX_FORMAT_INFO(TexFmt, ComponentSize, NumComponents, ComponentType) \ + FmtAttribs[ TexFmt ] = TextureFormatAttribs(TexFmt, #TexFmt, ComponentSize, NumComponents, ComponentType); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA32_TYPELESS, 4, 4, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA32_FLOAT, 4, 4, COMPONENT_TYPE_FLOAT ); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA32_UINT, 4, 4, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA32_SINT, 4, 4, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGB32_TYPELESS, 4, 3, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGB32_FLOAT, 4, 3, COMPONENT_TYPE_FLOAT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGB32_UINT, 4, 3, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGB32_SINT, 4, 3, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA16_TYPELESS, 2, 4, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA16_FLOAT, 2, 4, COMPONENT_TYPE_FLOAT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA16_UNORM, 2, 4, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA16_UINT, 2, 4, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA16_SNORM, 2, 4, COMPONENT_TYPE_SNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA16_SINT, 2, 4, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG32_TYPELESS, 4, 2, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG32_FLOAT, 4, 2, COMPONENT_TYPE_FLOAT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG32_UINT, 4, 2, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG32_SINT, 4, 2, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R32G8X24_TYPELESS, 4, 2, COMPONENT_TYPE_DEPTH_STENCIL); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_D32_FLOAT_S8X24_UINT, 4, 2, COMPONENT_TYPE_DEPTH_STENCIL); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS,4, 2, COMPONENT_TYPE_DEPTH_STENCIL); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_X32_TYPELESS_G8X24_UINT, 4, 2, COMPONENT_TYPE_DEPTH_STENCIL); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGB10A2_TYPELESS, 4, 1, COMPONENT_TYPE_COMPOUND); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGB10A2_UNORM, 4, 1, COMPONENT_TYPE_COMPOUND); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGB10A2_UINT, 4, 1, COMPONENT_TYPE_COMPOUND); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R11G11B10_FLOAT, 4, 1, COMPONENT_TYPE_COMPOUND); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA8_TYPELESS, 1, 4, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA8_UNORM, 1, 4, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA8_UNORM_SRGB, 1, 4, COMPONENT_TYPE_UNORM_SRGB); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA8_UINT, 1, 4, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA8_SNORM, 1, 4, COMPONENT_TYPE_SNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGBA8_SINT, 1, 4, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG16_TYPELESS, 2, 2, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG16_FLOAT, 2, 2, COMPONENT_TYPE_FLOAT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG16_UNORM, 2, 2, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG16_UINT, 2, 2, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG16_SNORM, 2, 2, COMPONENT_TYPE_SNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG16_SINT, 2, 2, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R32_TYPELESS, 4, 1, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_D32_FLOAT, 4, 1, COMPONENT_TYPE_DEPTH); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R32_FLOAT, 4, 1, COMPONENT_TYPE_FLOAT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R32_UINT, 4, 1, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R32_SINT, 4, 1, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R24G8_TYPELESS, 4, 1, COMPONENT_TYPE_DEPTH_STENCIL); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_D24_UNORM_S8_UINT, 4, 1, COMPONENT_TYPE_DEPTH_STENCIL); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R24_UNORM_X8_TYPELESS, 4, 1, COMPONENT_TYPE_DEPTH_STENCIL); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_X24_TYPELESS_G8_UINT, 4, 1, COMPONENT_TYPE_DEPTH_STENCIL); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG8_TYPELESS, 1, 2, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG8_UNORM, 1, 2, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG8_UINT, 1, 2, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG8_SNORM, 1, 2, COMPONENT_TYPE_SNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG8_SINT, 1, 2, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R16_TYPELESS, 2, 1, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R16_FLOAT, 2, 1, COMPONENT_TYPE_FLOAT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_D16_UNORM, 2, 1, COMPONENT_TYPE_DEPTH); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R16_UNORM, 2, 1, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R16_UINT, 2, 1, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R16_SNORM, 2, 1, COMPONENT_TYPE_SNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R16_SINT, 2, 1, COMPONENT_TYPE_SINT); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R8_TYPELESS, 1, 1, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R8_UNORM, 1, 1, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R8_UINT, 1, 1, COMPONENT_TYPE_UINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R8_SNORM, 1, 1, COMPONENT_TYPE_SNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R8_SINT, 1, 1, COMPONENT_TYPE_SINT); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_A8_UNORM, 1, 1, COMPONENT_TYPE_UNORM); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R1_UNORM, 1, 1, COMPONENT_TYPE_UNORM); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RGB9E5_SHAREDEXP, 4, 1, COMPONENT_TYPE_COMPOUND); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_RG8_B8G8_UNORM, 1, 4, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_G8R8_G8B8_UNORM, 1, 4, COMPONENT_TYPE_UNORM); + + // http://www.g-truc.net/post-0335.html + // http://renderingpipeline.com/2012/07/texture-compression/ + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC1_TYPELESS, 8, 3, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC1_UNORM, 8, 3, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC1_UNORM_SRGB, 8, 3, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC2_TYPELESS, 16, 4, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC2_UNORM, 16, 4, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC2_UNORM_SRGB, 16, 4, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC3_TYPELESS, 16, 4, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC3_UNORM, 16, 4, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC3_UNORM_SRGB, 16, 4, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC4_TYPELESS, 8, 1, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC4_UNORM, 8, 1, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC4_SNORM, 8, 1, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC5_TYPELESS, 16, 2, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC5_UNORM, 16, 2, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC5_SNORM, 16, 2, COMPONENT_TYPE_COMPRESSED); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_B5G6R5_UNORM, 2, 1, COMPONENT_TYPE_COMPOUND); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_B5G5R5A1_UNORM, 2, 1, COMPONENT_TYPE_COMPOUND); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BGRA8_UNORM, 1, 4, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BGRX8_UNORM, 1, 4, COMPONENT_TYPE_UNORM); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, 4, 1, COMPONENT_TYPE_COMPOUND); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BGRA8_TYPELESS, 1, 4, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BGRA8_UNORM_SRGB, 1, 4, COMPONENT_TYPE_UNORM_SRGB); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BGRX8_TYPELESS, 1, 4, COMPONENT_TYPE_UNDEFINED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BGRX8_UNORM_SRGB, 1, 4, COMPONENT_TYPE_UNORM_SRGB); + + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC6H_TYPELESS, 16, 3, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC6H_UF16, 16, 3, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC6H_SF16, 16, 3, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC7_TYPELESS, 16, 4, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC7_UNORM, 16, 4, COMPONENT_TYPE_COMPRESSED); + INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC7_UNORM_SRGB, 16, 4, COMPONENT_TYPE_COMPRESSED); +#undef INIT_TEX_FORMAT_INFO + static_assert(TEX_FORMAT_NUM_FORMATS == TEX_FORMAT_BC7_UNORM_SRGB + 1, "Not all texture formats initialized."); + +#ifdef _DEBUG + for( Uint32 Fmt = TEX_FORMAT_UNKNOWN; Fmt < TEX_FORMAT_NUM_FORMATS; ++Fmt ) + VERIFY(FmtAttribs[Fmt].Format == Fmt, "Uninitialized format"); +#endif + + bIsInit = true; + } + + if( Format >= TEX_FORMAT_UNKNOWN && Format < TEX_FORMAT_NUM_FORMATS ) + { + const auto &Attribs = FmtAttribs[Format]; + VERIFY( Attribs.Format == Format, "Unexpected format" ); + return Attribs; + } + else + { + UNEXPECTED( "Texture format (", Format, ") is out of allowed range [0, ", TEX_FORMAT_NUM_FORMATS-1, "]" ); + return FmtAttribs[0]; + } +} + + +const Char *GetTexViewTypeLiteralName( TEXTURE_VIEW_TYPE ViewType ) +{ + static const Char *TexViewLiteralNames[TEXTURE_VIEW_NUM_VIEWS] = {}; + static bool bIsInit = false; + // Note that this implementation is thread-safe + // Even if two threads try to call the function at the same time, + // the worst thing that might happen is that the array will be + // initialized multiple times. But the result will always be correct. + if( !bIsInit ) + { +#define INIT_TEX_VIEW_TYPE_NAME(ViewType)TexViewLiteralNames[ViewType] = #ViewType + INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_UNDEFINED ); + INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_SHADER_RESOURCE ); + INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_RENDER_TARGET ); + INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_DEPTH_STENCIL ); + INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_UNORDERED_ACCESS ); +#undef INIT_TEX_VIEW_TYPE_NAME + static_assert(TEXTURE_VIEW_NUM_VIEWS == TEXTURE_VIEW_UNORDERED_ACCESS + 1, "Not all texture views names initialized."); + + bIsInit = true; + } + + if( ViewType >= TEXTURE_VIEW_UNDEFINED && ViewType < TEXTURE_VIEW_NUM_VIEWS ) + { + return TexViewLiteralNames[ViewType]; + } + else + { + UNEXPECTED("Texture view type (", ViewType, ") is out of allowed range [0, ", TEXTURE_VIEW_NUM_VIEWS-1, "]" ); + return "<Unknown texture view type>"; + } +} + +const Char *GetBufferViewTypeLiteralName( BUFFER_VIEW_TYPE ViewType ) +{ + static const Char *BuffViewLiteralNames[BUFFER_VIEW_NUM_VIEWS] = {}; + static bool bIsInit = false; + // Note that this implementation is thread-safe + // Even if two threads try to call the function at the same time, + // the worst thing that might happen is that the array will be + // initialized multiple times. But the result will always be correct. + if( !bIsInit ) + { +#define INIT_BUFF_VIEW_TYPE_NAME(ViewType)BuffViewLiteralNames[ViewType] = #ViewType + INIT_BUFF_VIEW_TYPE_NAME( BUFFER_VIEW_UNDEFINED ); + INIT_BUFF_VIEW_TYPE_NAME( BUFFER_VIEW_SHADER_RESOURCE ); + INIT_BUFF_VIEW_TYPE_NAME( BUFFER_VIEW_UNORDERED_ACCESS ); + #undef INIT_BUFF_VIEW_TYPE_NAME + static_assert(BUFFER_VIEW_NUM_VIEWS == BUFFER_VIEW_UNORDERED_ACCESS + 1, "Not all buffer views names initialized."); + + bIsInit = true; + } + + if( ViewType >= BUFFER_VIEW_UNDEFINED && ViewType < BUFFER_VIEW_NUM_VIEWS ) + { + return BuffViewLiteralNames[ViewType]; + } + else + { + UNEXPECTED( "Buffer view type (", ViewType, ") is out of allowed range [0, ", BUFFER_VIEW_NUM_VIEWS-1, "]" ) + return "<Unknown buffer view type>"; + } +} + +const Char *GetShaderTypeLiteralName( SHADER_TYPE ShaderType ) +{ + switch( ShaderType ) + { +#define RETURN_SHADER_TYPE_NAME(ShaderType)\ + case ShaderType: return #ShaderType; + + RETURN_SHADER_TYPE_NAME( SHADER_TYPE_UNKNOWN ) + RETURN_SHADER_TYPE_NAME( SHADER_TYPE_VERTEX ) + RETURN_SHADER_TYPE_NAME( SHADER_TYPE_PIXEL ) + RETURN_SHADER_TYPE_NAME( SHADER_TYPE_GEOMETRY) + RETURN_SHADER_TYPE_NAME( SHADER_TYPE_HULL ) + RETURN_SHADER_TYPE_NAME( SHADER_TYPE_DOMAIN ) + RETURN_SHADER_TYPE_NAME( SHADER_TYPE_COMPUTE ) +#undef RETURN_SHADER_TYPE_NAME + + default: UNEXPECTED( "Unknown shader type" ); return "<Unknown shader type>"; + } +} + +/// Returns the string containing the usage +const Char* GetUsageString( USAGE Usage ) +{ + static const Char* UsageStrings[4]; + static bool bUsageStringsInit = false; + if( !bUsageStringsInit ) + { +#define INIT_USGAGE_STR(Usage)UsageStrings[Usage] = #Usage + INIT_USGAGE_STR( USAGE_STATIC ); + INIT_USGAGE_STR( USAGE_DEFAULT ); + INIT_USGAGE_STR( USAGE_DYNAMIC ); + INIT_USGAGE_STR( USAGE_CPU_ACCESSIBLE ); +#undef INIT_USGAGE_STR + bUsageStringsInit = true; + } + if( Usage >= USAGE_STATIC && Usage <= USAGE_CPU_ACCESSIBLE ) + return UsageStrings[Usage]; + else + { + UNEXPECTED("Unknow usage" ) + return "Unknown usage"; + } +} + +const Char* GetTextureTypeString( TEXTURE_TYPE TexType ) +{ + static const Char* TexTypeStrings[TEXTURE_TYPE_NUM_TYPES]; + static bool bTexTypeStrsInit = false; + if( !bTexTypeStrsInit ) + { + TexTypeStrings[TEXTURE_TYPE_UNDEFINED] = "Undefined"; + TexTypeStrings[TEXTURE_TYPE_1D] = "1D"; + TexTypeStrings[TEXTURE_TYPE_1D_ARRAY] = "1D Array"; + TexTypeStrings[TEXTURE_TYPE_2D] = "2D"; + TexTypeStrings[TEXTURE_TYPE_2D_ARRAY] = "2D Array"; + TexTypeStrings[TEXTURE_TYPE_3D] = "3D"; + TexTypeStrings[TEXTURE_TYPE_2D_ARRAY] = "Cube"; + TexTypeStrings[TEXTURE_TYPE_3D] = "Cube Array"; + static_assert(TEXTURE_TYPE_NUM_TYPES == TEXTURE_TYPE_CUBE_ARRAY + 1, "Not all texture type strings initialized."); + + bTexTypeStrsInit = true; + } + if( TexType >= TEXTURE_TYPE_UNDEFINED && TexType < TEXTURE_TYPE_NUM_TYPES ) + return TexTypeStrings[TexType]; + else + { + UNEXPECTED("Unknow texture type") + return "Unknow texture type"; + } +} + +static const Char* GetSingleBindFlagString( Uint32 BindFlag ) +{ + VERIFY( (BindFlag & (BindFlag - 1)) == 0, "More than one bind flag specified" ); + switch( BindFlag ) + { +#define BIND_FLAG_STR_CASE(Flag) case Flag: return #Flag; + BIND_FLAG_STR_CASE( BIND_VERTEX_BUFFER ) + BIND_FLAG_STR_CASE( BIND_INDEX_BUFFER ) + BIND_FLAG_STR_CASE( BIND_UNIFORM_BUFFER ) + BIND_FLAG_STR_CASE( BIND_SHADER_RESOURCE ) + BIND_FLAG_STR_CASE( BIND_STREAM_OUTPUT ) + BIND_FLAG_STR_CASE( BIND_RENDER_TARGET ) + BIND_FLAG_STR_CASE( BIND_DEPTH_STENCIL ) + BIND_FLAG_STR_CASE( BIND_UNORDERED_ACCESS ) + BIND_FLAG_STR_CASE( BIND_INDIRECT_DRAW_ARGS ) +#undef BIND_FLAG_STR_CASE + default: UNEXPECTED( "Unexpected bind flag ", BindFlag ); return ""; + } +} + +String GetBindFlagsString( Uint32 BindFlags ) +{ + if( BindFlags == 0 ) + return "0"; + String Str; + for( Uint32 Flag = BIND_VERTEX_BUFFER; BindFlags && Flag <= BIND_INDIRECT_DRAW_ARGS; Flag <<= 1 ) + { + if( BindFlags&Flag ) + { + if( Str.length() ) + Str += '|'; + Str += GetSingleBindFlagString( Flag ); + BindFlags &= ~Flag; + } + } + VERIFY( BindFlags == 0, "Unknown bind flags left" ); + return Str; +} + + +static const Char* GetSingleCPUAccessFlagString( Uint32 CPUAccessFlag ) +{ + VERIFY( (CPUAccessFlag & (CPUAccessFlag - 1)) == 0, "More than one access flag specified" ); + switch( CPUAccessFlag ) + { +#define CPU_ACCESS_FLAG_STR_CASE(Flag) case Flag: return #Flag; + CPU_ACCESS_FLAG_STR_CASE( CPU_ACCESS_READ ) + CPU_ACCESS_FLAG_STR_CASE( CPU_ACCESS_WRITE ) +#undef CPU_ACCESS_FLAG_STR_CASE + default: UNEXPECTED( "Unexpected CPU access flag ", CPUAccessFlag ); return ""; + } +} + +String GetCPUAccessFlagsString( Uint32 CpuAccessFlags ) +{ + if( CpuAccessFlags == 0 ) + return "0"; + String Str; + for( Uint32 Flag = CPU_ACCESS_READ; CpuAccessFlags && Flag <= CPU_ACCESS_WRITE; Flag <<= 1 ) + { + if( CpuAccessFlags&Flag ) + { + if( Str.length() ) + Str += '|'; + Str += GetSingleCPUAccessFlagString( Flag ); + CpuAccessFlags &= ~Flag; + } + } + VERIFY( CpuAccessFlags == 0, "Unknown CPU access flags left" ); + return Str; +} + +// There is a nice standard function to_string, but there is a bug on gcc +// and it does not work +template<typename T> +String ToString( T Val ) +{ + std::stringstream ss; + ss << Val; + return ss.str(); +} + +String GetTextureDescString( const TextureDesc &Desc ) +{ + String Str = "Type: "; + Str += GetTextureTypeString(Desc.Type); + Str += "; size: "; + Str += ToString(Desc.Width); + if( Desc.Type == TEXTURE_TYPE_2D || Desc.Type == TEXTURE_TYPE_2D_ARRAY || Desc.Type == TEXTURE_TYPE_3D) + { + Str += "x"; + Str += ToString( Desc.Height ); + } + + if( Desc.Type == TEXTURE_TYPE_3D ) + { + Str += "x"; + Str += ToString( Desc.Depth ); + } + + if( Desc.Type == TEXTURE_TYPE_1D_ARRAY || Desc.Type == TEXTURE_TYPE_2D_ARRAY ) + { + Str += "; Num Slices: "; + Str += ToString( Desc.ArraySize ); + } + + auto FmtName = GetTextureFormatAttribs( Desc.Format ).Name; + Str += "; Format: "; + Str += FmtName; + + Str += "; Mip levels: "; + Str += ToString( Desc.MipLevels ); + + Str += "; Sample Count: "; + Str += ToString( Desc.SampleCount ); + + Str += "; Usage: "; + Str += GetUsageString(Desc.Usage); + + Str += "; Bind Flags: "; + Str += GetBindFlagsString(Desc.BindFlags); + + Str += "; CPU access: "; + Str += GetCPUAccessFlagsString(Desc.CPUAccessFlags); + + return Str; +} + +static const Char* GetBufferModeString( BUFFER_MODE Mode ) +{ + static const Char* BufferModeStrings[BUFFER_MODE_NUM_MODES]; + static bool bBuffModeStringsInit = false; + if( !bBuffModeStringsInit ) + { +#define INIT_BUFF_MODE_STR(Mode)BufferModeStrings[Mode] = #Mode + INIT_BUFF_MODE_STR( BUFFER_MODE_UNDEFINED ); + INIT_BUFF_MODE_STR( BUFFER_MODE_FORMATED ); + INIT_BUFF_MODE_STR( BUFFER_MODE_STRUCTURED ); +#undef INIT_BUFF_MODE_STR + static_assert(BUFFER_MODE_NUM_MODES == BUFFER_MODE_STRUCTURED + 1, "Not all buffer mode strings initialized."); + bBuffModeStringsInit = true; + } + if( Mode >= BUFFER_MODE_UNDEFINED && Mode < BUFFER_MODE_NUM_MODES ) + return BufferModeStrings[Mode]; + else + { + UNEXPECTED( "Unknown buffer mode" ); + return "Unknown buffer mode"; + } +} + +String GetBufferDescString( const BufferDesc &Desc ) +{ + String Str; + Str += "Size: "; + bool bIsLarge = false; + if( Desc.uiSizeInBytes > (1 << 20) ) + { + Str += ToString( Desc.uiSizeInBytes / (1<<20) ); + Str += " Mb ("; + bIsLarge = true; + } + else if( Desc.uiSizeInBytes > (1 << 10) ) + { + Str += ToString( Desc.uiSizeInBytes / (1<<10) ); + Str += " Kb ("; + bIsLarge = true; + } + + Str += ToString( Desc.uiSizeInBytes ); + Str += " bytes"; + if( bIsLarge ) + Str += ')'; + + Str += "; Mode: "; + Str += GetBufferModeString(Desc.Mode); + if( Desc.Mode == BUFFER_MODE_FORMATED ) + { + Str += "; Format: "; + Str += GetValueTypeString( Desc.Format.ValueType ); + if( Desc.Format.IsNormalized ) + Str += " norm"; + Str += " x "; + Str += ToString(Desc.Format.NumComponents); + } + + Str += "; Usage: "; + Str += GetUsageString(Desc.Usage); + + Str += "; Bind Flags: "; + Str += GetBindFlagsString(Desc.BindFlags); + + Str += "; CPU access: "; + Str += GetCPUAccessFlagsString(Desc.CPUAccessFlags); + + Str += "; stride: "; + Str += ToString( Desc.ElementByteStride ); + Str += " bytes"; + + return Str; +} + +Uint32 ComputeMipLevelsCount( Uint32 Width ) +{ + Uint32 MipLevels = 0; + while( (Width >> MipLevels) > 1 ) + ++MipLevels; + return MipLevels; +} + +Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height ) +{ + return ComputeMipLevelsCount( std::max( Width, Height ) ); +} + +Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height, Uint32 Depth ) +{ + return ComputeMipLevelsCount( std::max(std::max( Width, Height ), Depth) ); +} + +void CreateUniformBuffer( IRenderDevice *pDevice, Uint32 Size, IBuffer **ppBuffer, USAGE Usage, Uint32 BindFlag, Uint32 CPUAccessFlags) +{ + BufferDesc CBDesc; + CBDesc.uiSizeInBytes = Size; + CBDesc.Usage = Usage; + CBDesc.BindFlags = BindFlag; + CBDesc.CPUAccessFlags = CPUAccessFlags; + pDevice->CreateBuffer( CBDesc, BufferData(), ppBuffer ); +} + +} diff --git a/Graphics/GraphicsTools/src/pch.cpp b/Graphics/GraphicsTools/src/pch.cpp new file mode 100644 index 00000000..809315e1 --- /dev/null +++ b/Graphics/GraphicsTools/src/pch.cpp @@ -0,0 +1,24 @@ +/* Copyright 2015 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" diff --git a/Graphics/Shared/build/Windows/DLLCommon.props b/Graphics/Shared/build/Windows/DLLCommon.props new file mode 100644 index 00000000..0d999b8f --- /dev/null +++ b/Graphics/Shared/build/Windows/DLLCommon.props @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <OutDir>$(SolutionDir)\bin\DLLs\$(PlatformShortName)\</OutDir> + <TargetName>$(ProjectName)_$(ConfigSuffix)</TargetName> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>ENGINE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup /> +</Project>
\ No newline at end of file |
