123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // HlslTestUtils.h //
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- // This file is distributed under the University of Illinois Open Source //
- // License. See LICENSE.TXT for details. //
- // //
- // Provides utility functions for HLSL tests. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include <string>
- #include <sstream>
- #include <fstream>
- #include <atomic>
- #include <cmath>
- #include <vector>
- #include <algorithm>
- #ifdef _WIN32
- #include <dxgiformat.h>
- #include "WexTestClass.h"
- #else
- #include "WEXAdapter.h"
- #endif
- #include "dxc/Support/Unicode.h"
- #include "dxc/DXIL/DxilConstants.h" // DenormMode
- using namespace std;
- #ifndef HLSLDATAFILEPARAM
- #define HLSLDATAFILEPARAM L"HlslDataDir"
- #endif
- // If TAEF verify macros are available, use them to alias other legacy
- // comparison macros that don't have a direct translation.
- //
- // Other common replacements are as follows.
- //
- // EXPECT_EQ -> VERIFY_ARE_EQUAL
- // ASSERT_EQ -> VERIFY_ARE_EQUAL
- //
- // Note that whether verification throws or continues depends on
- // preprocessor settings.
- #ifdef VERIFY_ARE_EQUAL
- #ifndef EXPECT_STREQ
- #define EXPECT_STREQ(a, b) VERIFY_ARE_EQUAL(0, strcmp(a, b))
- #endif
- #define EXPECT_STREQW(a, b) VERIFY_ARE_EQUAL(0, wcscmp(a, b))
- #define VERIFY_ARE_EQUAL_CMP(a, b, ...) VERIFY_IS_TRUE(a == b, __VA_ARGS__)
- #define VERIFY_ARE_EQUAL_STR(a, b) { \
- const char *pTmpA = (a);\
- const char *pTmpB = (b);\
- if (0 != strcmp(pTmpA, pTmpB)) {\
- CA2W conv(pTmpB, CP_UTF8); WEX::Logging::Log::Comment(conv);\
- const char *pA = pTmpA; const char *pB = pTmpB; \
- while(*pA == *pB) { pA++; pB++; } \
- wchar_t diffMsg[32]; swprintf_s(diffMsg, _countof(diffMsg), L"diff at %u", (unsigned)(pA-pTmpA)); \
- WEX::Logging::Log::Comment(diffMsg); \
- } \
- VERIFY_ARE_EQUAL(0, strcmp(pTmpA, pTmpB)); \
- }
- #define VERIFY_ARE_EQUAL_WSTR(a, b) { \
- if (0 != wcscmp(a, b)) { WEX::Logging::Log::Comment(b);} \
- VERIFY_ARE_EQUAL(0, wcscmp(a, b)); \
- }
- #ifndef ASSERT_EQ
- #define ASSERT_EQ(expected, actual) VERIFY_ARE_EQUAL(expected, actual)
- #endif
- #ifndef ASSERT_NE
- #define ASSERT_NE(expected, actual) VERIFY_ARE_NOT_EQUAL(expected, actual)
- #endif
- #ifndef TEST_F
- #define TEST_F(typeName, functionName) void typeName::functionName()
- #endif
- #define ASSERT_HRESULT_SUCCEEDED VERIFY_SUCCEEDED
- #ifndef EXPECT_EQ
- #define EXPECT_EQ(expected, actual) VERIFY_ARE_EQUAL(expected, actual)
- #endif
- #endif // VERIFY_ARE_EQUAL
- static constexpr char whitespaceChars[] = " \t\r\n";
- static std::string strltrim(const std::string &value) {
- size_t first = value.find_first_not_of(whitespaceChars);
- return first == string::npos ? value : value.substr(first);
- }
- static std::string strrtrim(const std::string &value) {
- size_t last = value.find_last_not_of(whitespaceChars);
- return last == string::npos ? value : value.substr(0, last + 1);
- }
- static std::string strtrim(const std::string &value) {
- return strltrim(strrtrim(value));
- }
- static bool strstartswith(const std::string& value, const char* pattern) {
- for (size_t i = 0; ; ++i) {
- if (pattern[i] == '\0') return true;
- if (i == value.size() || value[i] != pattern[i]) return false;
- }
- }
- static std::vector<std::string> strtok(const std::string &value, const char *delimiters = whitespaceChars) {
- size_t searchOffset = 0;
- std::vector<std::string> tokens;
- while (searchOffset != value.size()) {
- size_t tokenStartIndex = value.find_first_not_of(delimiters, searchOffset);
- if (tokenStartIndex == std::string::npos) break;
- size_t tokenEndIndex = value.find_first_of(delimiters, tokenStartIndex);
- if (tokenEndIndex == std::string::npos) tokenEndIndex = value.size();
- tokens.emplace_back(value.substr(tokenStartIndex, tokenEndIndex - tokenStartIndex));
- searchOffset = tokenEndIndex;
- }
- return tokens;
- }
- namespace hlsl_test {
- inline std::wstring
- vFormatToWString(_In_z_ _Printf_format_string_ const wchar_t *fmt, va_list argptr) {
- std::wstring result;
- #ifdef _WIN32
- int len = _vscwprintf(fmt, argptr);
- result.resize(len + 1);
- vswprintf_s((wchar_t *)result.data(), len + 1, fmt, argptr);
- #else
- wchar_t fmtOut[1000];
- int len = vswprintf(fmtOut, 1000, fmt, argptr);
- assert(len >= 0 && "Too long formatted string in vFormatToWstring");
- result = fmtOut;
- #endif
- return result;
- }
- inline std::wstring
- FormatToWString(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) {
- va_list args;
- va_start(args, fmt);
- std::wstring result(vFormatToWString(fmt, args));
- va_end(args);
- return result;
- }
- inline void LogCommentFmt(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) {
- va_list args;
- va_start(args, fmt);
- std::wstring buf(vFormatToWString(fmt, args));
- va_end(args);
- WEX::Logging::Log::Comment(buf.data());
- }
- inline void LogErrorFmt(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) {
- va_list args;
- va_start(args, fmt);
- std::wstring buf(vFormatToWString(fmt, args));
- va_end(args);
- WEX::Logging::Log::Error(buf.data());
- }
- inline std::wstring GetPathToHlslDataFile(const wchar_t* relative) {
- WEX::TestExecution::SetVerifyOutput verifySettings(WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
- WEX::Common::String HlslDataDirValue;
- ASSERT_HRESULT_SUCCEEDED(WEX::TestExecution::RuntimeParameters::TryGetValue(HLSLDATAFILEPARAM, HlslDataDirValue));
- wchar_t envPath[MAX_PATH];
- wchar_t expanded[MAX_PATH];
- swprintf_s(envPath, _countof(envPath), L"%ls\\%ls", reinterpret_cast<const wchar_t*>(HlslDataDirValue.GetBuffer()), relative);
- VERIFY_WIN32_BOOL_SUCCEEDED(ExpandEnvironmentStringsW(envPath, expanded, _countof(expanded)));
- return std::wstring(expanded);
- }
- inline bool PathLooksAbsolute(LPCWSTR name) {
- // Very simplified, only for the cases we care about in the test suite.
- #ifdef _WIN32
- return name && *name && ((*name == L'\\') || (name[1] == L':'));
- #else
- return name && *name && (*name == L'/');
- #endif
- }
- static bool HasRunLine(std::string &line) {
- const char *delimiters = " ;/";
- auto lineelems = strtok(line, delimiters);
- return !lineelems.empty() &&
- lineelems.front().compare("RUN:") == 0;
- }
- inline std::vector<std::string> GetRunLines(const LPCWSTR name) {
- const std::wstring path = PathLooksAbsolute(name)
- ? std::wstring(name)
- : hlsl_test::GetPathToHlslDataFile(name);
- #ifdef _WIN32
- std::ifstream infile(path);
- #else
- std::ifstream infile((CW2A(path.c_str())));
- #endif
- if (infile.bad()) {
- std::wstring errMsg(L"Unable to read file ");
- errMsg += path;
- WEX::Logging::Log::Error(errMsg.c_str());
- VERIFY_FAIL();
- }
- std::vector<std::string> runlines;
- std::string line;
- constexpr size_t runlinesize = 300;
- while (std::getline(infile, line)) {
- if (!HasRunLine(line))
- continue;
- char runline[runlinesize];
- memset(runline, 0, runlinesize);
- memcpy(runline, line.c_str(), min(runlinesize, line.size()));
- runlines.emplace_back(runline);
- }
- return runlines;
- }
- inline std::string GetFirstLine(LPCWSTR name) {
- char firstLine[300];
- memset(firstLine, 0, sizeof(firstLine));
- const std::wstring path = PathLooksAbsolute(name)
- ? std::wstring(name)
- : hlsl_test::GetPathToHlslDataFile(name);
- #ifdef _WIN32
- std::ifstream infile(path);
- #else
- std::ifstream infile((CW2A(path.c_str())));
- #endif
- if (infile.bad()) {
- std::wstring errMsg(L"Unable to read file ");
- errMsg += path;
- WEX::Logging::Log::Error(errMsg.c_str());
- VERIFY_FAIL();
- }
- infile.getline(firstLine, _countof(firstLine));
- return firstLine;
- }
- inline HANDLE CreateFileForReading(LPCWSTR path) {
- HANDLE sourceHandle = CreateFileW(path, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
- if (sourceHandle == INVALID_HANDLE_VALUE) {
- DWORD err = GetLastError();
- std::wstring errorMessage(FormatToWString(L"Unable to open file '%s', err=%u", path, err).c_str());
- VERIFY_SUCCEEDED(HRESULT_FROM_WIN32(err), errorMessage.c_str());
- }
- return sourceHandle;
- }
- inline HANDLE CreateNewFileForReadWrite(LPCWSTR path) {
- HANDLE sourceHandle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
- if (sourceHandle == INVALID_HANDLE_VALUE) {
- DWORD err = GetLastError();
- std::wstring errorMessage(FormatToWString(L"Unable to create file '%s', err=%u", path, err).c_str());
- VERIFY_SUCCEEDED(HRESULT_FROM_WIN32(err), errorMessage.c_str());
- }
- return sourceHandle;
- }
- inline bool GetTestParamBool(LPCWSTR name) {
- WEX::Common::String ParamValue;
- WEX::Common::String NameValue;
- if (FAILED(WEX::TestExecution::RuntimeParameters::TryGetValue(name,
- ParamValue))) {
- return false;
- }
- if (ParamValue.IsEmpty()) {
- return false;
- }
- if (0 == wcscmp(ParamValue, L"*")) {
- return true;
- }
- VERIFY_SUCCEEDED(WEX::TestExecution::RuntimeParameters::TryGetValue(
- L"TestName", NameValue));
- if (NameValue.IsEmpty()) {
- return false;
- }
- return Unicode::IsStarMatchUTF16(ParamValue, ParamValue.GetLength(),
- NameValue, NameValue.GetLength());
- }
- inline bool GetTestParamUseWARP(bool defaultVal) {
- WEX::Common::String AdapterValue;
- if (FAILED(WEX::TestExecution::RuntimeParameters::TryGetValue(
- L"Adapter", AdapterValue))) {
- return defaultVal;
- }
- if ((defaultVal && AdapterValue.IsEmpty()) ||
- AdapterValue.CompareNoCase(L"WARP") == 0) {
- return true;
- }
- return false;
- }
- }
- #ifdef FP_SUBNORMAL
- inline bool isdenorm(float f) {
- return FP_SUBNORMAL == std::fpclassify(f);
- }
- #else
- inline bool isdenorm(float f) {
- return (std::numeric_limits<float>::denorm_min() <= f && f < std::numeric_limits<float>::min()) ||
- (-std::numeric_limits<float>::min() < f && f <= -std::numeric_limits<float>::denorm_min());
- }
- #endif // FP_SUBNORMAL
- inline float ifdenorm_flushf(float a) {
- return isdenorm(a) ? copysign(0.0f, a) : a;
- }
- inline bool ifdenorm_flushf_eq(float a, float b) {
- return ifdenorm_flushf(a) == ifdenorm_flushf(b);
- }
- static const uint16_t Float16NaN = 0xff80;
- static const uint16_t Float16PosInf = 0x7c00;
- static const uint16_t Float16NegInf = 0xfc00;
- static const uint16_t Float16PosDenorm = 0x0008;
- static const uint16_t Float16NegDenorm = 0x8008;
- static const uint16_t Float16PosZero = 0x0000;
- static const uint16_t Float16NegZero = 0x8000;
- inline bool GetSign(float x) {
- return std::signbit(x);
- }
- inline int GetMantissa(float x) {
- int bits = reinterpret_cast<int &>(x);
- return bits & 0x7fffff;
- }
- inline int GetExponent(float x) {
- int bits = reinterpret_cast<int &>(x);
- return (bits >> 23) & 0xff;
- }
- #define FLOAT16_BIT_SIGN 0x8000
- #define FLOAT16_BIT_EXP 0x7c00
- #define FLOAT16_BIT_MANTISSA 0x03ff
- #define FLOAT16_BIGGEST_DENORM FLOAT16_BIT_MANTISSA
- #define FLOAT16_BIGGEST_NORMAL 0x7bff
- inline bool isnanFloat16(uint16_t val) {
- return (val & FLOAT16_BIT_EXP) == FLOAT16_BIT_EXP &&
- (val & FLOAT16_BIT_MANTISSA) != 0;
- }
- inline uint16_t ConvertFloat32ToFloat16(float val) {
- union Bits {
- uint32_t u_bits;
- float f_bits;
- };
- static const uint32_t SignMask = 0x8000;
- // Minimum f32 value representable in f16 format without denormalizing
- static const uint32_t Min16in32 = 0x38800000;
- // Maximum f32 value (next to infinity)
- static const uint32_t Max32 = 0x7f7FFFFF;
- // Mask for f32 mantissa
- static const uint32_t Fraction32Mask = 0x007FFFFF;
- // pow(2,24)
- static const uint32_t DenormalRatio = 0x4B800000;
- static const uint32_t NormalDelta = 0x38000000;
- Bits bits;
- bits.f_bits = val;
- uint32_t sign = bits.u_bits & (SignMask << 16);
- Bits Abs;
- Abs.u_bits = bits.u_bits ^ sign;
- bool isLessThanNormal = Abs.f_bits < *(const float*)&Min16in32;
- bool isInfOrNaN = Abs.u_bits > Max32;
- if (isLessThanNormal) {
- // Compute Denormal result
- return (uint16_t)(Abs.f_bits * *(const float*)(&DenormalRatio)) | (uint16_t)(sign >> 16);
- }
- else if (isInfOrNaN) {
- // Compute Inf or Nan result
- uint32_t Fraction = Abs.u_bits & Fraction32Mask;
- uint16_t IsNaN = Fraction == 0 ? 0 : 0xffff;
- return (IsNaN & FLOAT16_BIT_MANTISSA) | FLOAT16_BIT_EXP | (uint16_t)(sign >> 16);
- }
- else {
- // Compute Normal result
- return (uint16_t)((Abs.u_bits - NormalDelta) >> 13) | (uint16_t)(sign >> 16);
- }
- }
- inline float ConvertFloat16ToFloat32(uint16_t x) {
- union Bits {
- float f_bits;
- uint32_t u_bits;
- };
- uint32_t Sign = (x & FLOAT16_BIT_SIGN) << 16;
- // nan -> exponent all set and mantisa is non zero
- // +/-inf -> exponent all set and mantissa is zero
- // denorm -> exponent zero and significand nonzero
- uint32_t Abs = (x & 0x7fff);
- uint32_t IsNormal = Abs > FLOAT16_BIGGEST_DENORM;
- uint32_t IsInfOrNaN = Abs > FLOAT16_BIGGEST_NORMAL;
- // Signless Result for normals
- uint32_t DenormRatio = 0x33800000;
- float DenormResult = Abs * (*(float*)&DenormRatio);
- uint32_t AbsShifted = Abs << 13;
- // Signless Result for normals
- uint32_t NormalResult = AbsShifted + 0x38000000;
- // Signless Result for int & nans
- uint32_t InfResult = AbsShifted + 0x70000000;
- Bits bits;
- bits.u_bits = 0;
- if (IsInfOrNaN)
- bits.u_bits |= InfResult;
- else if (IsNormal)
- bits.u_bits |= NormalResult;
- else
- bits.f_bits = DenormResult;
- bits.u_bits |= Sign;
- return bits.f_bits;
- }
- uint16_t ConvertFloat32ToFloat16(float val);
- float ConvertFloat16ToFloat32(uint16_t val);
- inline bool CompareFloatULP(const float &fsrc, const float &fref, int ULPTolerance,
- hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
- if (fsrc == fref) {
- return true;
- }
- if (std::isnan(fsrc)) {
- return std::isnan(fref);
- }
- if (mode == hlsl::DXIL::Float32DenormMode::Any) {
- // If denorm expected, output can be sign preserved zero. Otherwise output
- // should pass the regular ulp testing.
- if (isdenorm(fref) && fsrc == 0 && std::signbit(fsrc) == std::signbit(fref))
- return true;
- }
- // For FTZ or Preserve mode, we should get the expected number within
- // ULPTolerance for any operations.
- int diff = *((const DWORD *)&fsrc) - *((const DWORD *)&fref);
- unsigned int uDiff = diff < 0 ? -diff : diff;
- return uDiff <= (unsigned int)ULPTolerance;
- }
- inline bool CompareFloatEpsilon(const float &fsrc, const float &fref, float epsilon,
- hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
- if (fsrc == fref) {
- return true;
- }
- if (std::isnan(fsrc)) {
- return std::isnan(fref);
- }
- if (mode == hlsl::DXIL::Float32DenormMode::Any) {
- // If denorm expected, output can be sign preserved zero. Otherwise output
- // should pass the regular epsilon testing.
- if (isdenorm(fref) && fsrc == 0 && std::signbit(fsrc) == std::signbit(fref))
- return true;
- }
- // For FTZ or Preserve mode, we should get the expected number within
- // epsilon for any operations.
- return fabsf(fsrc - fref) < epsilon;
- }
- // Compare using relative error (relative error < 2^{nRelativeExp})
- inline bool CompareFloatRelativeEpsilon(const float &fsrc, const float &fref, int nRelativeExp,
- hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
- return CompareFloatULP(fsrc, fref, 23 - nRelativeExp, mode);
- }
- inline bool CompareHalfULP(const uint16_t &fsrc, const uint16_t &fref, float ULPTolerance) {
- if (fsrc == fref)
- return true;
- if (isnanFloat16(fsrc))
- return isnanFloat16(fref);
- // 16-bit floating point numbers must preserve denorms
- int diff = fsrc - fref;
- unsigned int uDiff = diff < 0 ? -diff : diff;
- return uDiff <= (unsigned int)ULPTolerance;
- }
- inline bool CompareHalfEpsilon(const uint16_t &fsrc, const uint16_t &fref, float epsilon) {
- if (fsrc == fref)
- return true;
- if (isnanFloat16(fsrc))
- return isnanFloat16(fref);
- float src_f32 = ConvertFloat16ToFloat32(fsrc);
- float ref_f32 = ConvertFloat16ToFloat32(fref);
- return std::abs(src_f32-ref_f32) < epsilon;
- }
- inline bool CompareHalfRelativeEpsilon(const uint16_t &fsrc, const uint16_t &fref, int nRelativeExp) {
- return CompareHalfULP(fsrc, fref, (float)(10 - nRelativeExp));
- }
- #ifdef _WIN32
- // returns the number of bytes per pixel for a given dxgi format
- // add more cases if different format needed to copy back resources
- inline UINT GetByteSizeForFormat(DXGI_FORMAT value) {
- switch (value) {
- case DXGI_FORMAT_R32G32B32A32_TYPELESS: return 16;
- case DXGI_FORMAT_R32G32B32A32_FLOAT: return 16;
- case DXGI_FORMAT_R32G32B32A32_UINT: return 16;
- case DXGI_FORMAT_R32G32B32A32_SINT: return 16;
- case DXGI_FORMAT_R32G32B32_TYPELESS: return 12;
- case DXGI_FORMAT_R32G32B32_FLOAT: return 12;
- case DXGI_FORMAT_R32G32B32_UINT: return 12;
- case DXGI_FORMAT_R32G32B32_SINT: return 12;
- case DXGI_FORMAT_R16G16B16A16_TYPELESS: return 8;
- case DXGI_FORMAT_R16G16B16A16_FLOAT: return 8;
- case DXGI_FORMAT_R16G16B16A16_UNORM: return 8;
- case DXGI_FORMAT_R16G16B16A16_UINT: return 8;
- case DXGI_FORMAT_R16G16B16A16_SNORM: return 8;
- case DXGI_FORMAT_R16G16B16A16_SINT: return 8;
- case DXGI_FORMAT_R32G32_TYPELESS: return 8;
- case DXGI_FORMAT_R32G32_FLOAT: return 8;
- case DXGI_FORMAT_R32G32_UINT: return 8;
- case DXGI_FORMAT_R32G32_SINT: return 8;
- case DXGI_FORMAT_R32G8X24_TYPELESS: return 8;
- case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return 4;
- case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return 4;
- case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return 4;
- case DXGI_FORMAT_R10G10B10A2_TYPELESS: return 4;
- case DXGI_FORMAT_R10G10B10A2_UNORM: return 4;
- case DXGI_FORMAT_R10G10B10A2_UINT: return 4;
- case DXGI_FORMAT_R11G11B10_FLOAT: return 4;
- case DXGI_FORMAT_R8G8B8A8_TYPELESS: return 4;
- case DXGI_FORMAT_R8G8B8A8_UNORM: return 4;
- case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return 4;
- case DXGI_FORMAT_R8G8B8A8_UINT: return 4;
- case DXGI_FORMAT_R8G8B8A8_SNORM: return 4;
- case DXGI_FORMAT_R8G8B8A8_SINT: return 4;
- case DXGI_FORMAT_R16G16_TYPELESS: return 4;
- case DXGI_FORMAT_R16G16_FLOAT: return 4;
- case DXGI_FORMAT_R16G16_UNORM: return 4;
- case DXGI_FORMAT_R16G16_UINT: return 4;
- case DXGI_FORMAT_R16G16_SNORM: return 4;
- case DXGI_FORMAT_R16G16_SINT: return 4;
- case DXGI_FORMAT_R32_TYPELESS: return 4;
- case DXGI_FORMAT_D32_FLOAT: return 4;
- case DXGI_FORMAT_R32_FLOAT: return 4;
- case DXGI_FORMAT_R32_UINT: return 4;
- case DXGI_FORMAT_R32_SINT: return 4;
- case DXGI_FORMAT_R24G8_TYPELESS: return 4;
- case DXGI_FORMAT_D24_UNORM_S8_UINT: return 4;
- case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return 4;
- case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return 4;
- case DXGI_FORMAT_R8G8_TYPELESS: return 2;
- case DXGI_FORMAT_R8G8_UNORM: return 2;
- case DXGI_FORMAT_R8G8_UINT: return 2;
- case DXGI_FORMAT_R8G8_SNORM: return 2;
- case DXGI_FORMAT_R8G8_SINT: return 2;
- case DXGI_FORMAT_R16_TYPELESS: return 2;
- case DXGI_FORMAT_R16_FLOAT: return 2;
- case DXGI_FORMAT_D16_UNORM: return 2;
- case DXGI_FORMAT_R16_UNORM: return 2;
- case DXGI_FORMAT_R16_UINT: return 2;
- case DXGI_FORMAT_R16_SNORM: return 2;
- case DXGI_FORMAT_R16_SINT: return 2;
- case DXGI_FORMAT_R8_TYPELESS: return 1;
- case DXGI_FORMAT_R8_UNORM: return 1;
- case DXGI_FORMAT_R8_UINT: return 1;
- case DXGI_FORMAT_R8_SNORM: return 1;
- case DXGI_FORMAT_R8_SINT: return 1;
- case DXGI_FORMAT_A8_UNORM: return 1;
- case DXGI_FORMAT_R1_UNORM: return 1;
- default:
- VERIFY_FAILED(E_INVALIDARG);
- return 0;
- }
- }
- #endif
|