New upstream version 25.0.3+dfsg1

This commit is contained in:
Sebastian Ramacher 2020-03-25 09:07:22 +01:00
parent 04fe0efc67
commit 8b2e5f2130
569 changed files with 62491 additions and 5875 deletions

View file

@ -26,6 +26,7 @@ set(libobs-d3d11_SOURCES
d3d11-stagesurf.cpp
d3d11-subsystem.cpp
d3d11-texture2d.cpp
d3d11-texture3d.cpp
d3d11-vertexbuffer.cpp
d3d11-duplicator.cpp
d3d11-rebuild.cpp
@ -33,6 +34,7 @@ set(libobs-d3d11_SOURCES
set(libobs-d3d11_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/d3d11-config.h
intel-nv12-support.hpp
d3d11-shaderprocessor.hpp
d3d11-subsystem.hpp)

View file

@ -251,6 +251,67 @@ void gs_timer_range::Rebuild(ID3D11Device *dev)
throw HRError("Failed to create timer", hr);
}
void gs_texture_3d::RebuildSharedTextureFallback()
{
td = {};
td.Width = 2;
td.Height = 2;
td.Depth = 2;
td.MipLevels = 1;
td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
td.BindFlags = D3D11_BIND_SHADER_RESOURCE;
width = td.Width;
height = td.Height;
depth = td.Depth;
dxgiFormat = td.Format;
levels = 1;
resourceDesc = {};
resourceDesc.Format = td.Format;
resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
resourceDesc.Texture3D.MostDetailedMip = 0;
resourceDesc.Texture3D.MipLevels = 1;
isShared = false;
}
void gs_texture_3d::Rebuild(ID3D11Device *dev)
{
HRESULT hr;
if (isShared) {
hr = dev->OpenSharedResource((HANDLE)(uintptr_t)sharedHandle,
__uuidof(ID3D11Texture3D),
(void **)&texture);
if (FAILED(hr)) {
blog(LOG_WARNING,
"Failed to rebuild shared texture: ", "0x%08lX",
hr);
RebuildSharedTextureFallback();
}
}
if (!isShared) {
hr = dev->CreateTexture3D(
&td, data.size() ? srd.data() : nullptr, &texture);
if (FAILED(hr))
throw HRError("Failed to create 3D texture", hr);
}
hr = dev->CreateShaderResourceView(texture, &resourceDesc, &shaderRes);
if (FAILED(hr))
throw HRError("Failed to create resource view", hr);
acquired = false;
if ((td.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0) {
ComQIPtr<IDXGIResource> dxgi_res(texture);
if (dxgi_res)
GetSharedHandle(dxgi_res);
device_texture_acquire_sync(this, 0, INFINITE);
}
}
void SavedBlendState::Rebuild(ID3D11Device *dev)
{
HRESULT hr = dev->CreateBlendState(&bd, &state);
@ -276,7 +337,6 @@ const static D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
};
void gs_device::RebuildDevice()
@ -288,6 +348,9 @@ try {
/* ----------------------------------------------------------------- */
for (gs_device_loss &callback : loss_callbacks)
callback.device_loss_release(callback.data);
gs_obj *obj = first_obj;
while (obj) {
@ -328,6 +391,9 @@ try {
case gs_type::gs_timer_range:
((gs_timer_range *)obj)->Release();
break;
case gs_type::gs_texture_3d:
((gs_texture_3d *)obj)->Release();
break;
}
obj = obj->next;
@ -341,6 +407,7 @@ try {
state.Release();
context->ClearState();
context->Flush();
context.Release();
device.Release();
@ -410,6 +477,9 @@ try {
case gs_type::gs_timer_range:
((gs_timer_range *)obj)->Rebuild(dev);
break;
case gs_type::gs_texture_3d:
((gs_texture_3d *)obj)->Rebuild(dev);
break;
}
obj = obj->next;
@ -440,6 +510,9 @@ try {
for (auto &state : blendStates)
state.Rebuild(dev);
for (gs_device_loss &callback : loss_callbacks)
callback.device_loss_rebuild(device.Get(), callback.data);
} catch (const char *error) {
bcrash("Failed to recreate D3D11: %s", error);

View file

@ -25,6 +25,7 @@
#include <d3d9.h>
#include "d3d11-subsystem.hpp"
#include "d3d11-config.h"
#include "intel-nv12-support.hpp"
struct UnsupportedHWError : HRError {
inline UnsupportedHWError(const char *str, HRESULT hr)
@ -231,7 +232,6 @@ const static D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
};
/* ------------------------------------------------------------------------- */
@ -353,6 +353,25 @@ try {
return false;
}
static bool increase_maximum_frame_latency(ID3D11Device *device)
{
ComQIPtr<IDXGIDevice1> dxgiDevice(device);
if (!dxgiDevice) {
blog(LOG_DEBUG, "%s: Failed to get IDXGIDevice1", __FUNCTION__);
return false;
}
const HRESULT hr = dxgiDevice->SetMaximumFrameLatency(16);
if (FAILED(hr)) {
blog(LOG_DEBUG, "%s: SetMaximumFrameLatency failed",
__FUNCTION__);
return false;
}
blog(LOG_INFO, "DXGI increase maximum frame latency success");
return true;
}
#if USE_GPU_PRIORITY
static bool set_priority(ID3D11Device *device)
{
@ -404,17 +423,13 @@ static bool set_priority(ID3D11Device *device)
return true;
}
static bool is_intel(const wstring &name)
{
return wstrstri(name.c_str(), L"intel") != nullptr;
}
#endif
void gs_device::InitDevice(uint32_t adapterIdx)
{
wstring adapterName;
DXGI_ADAPTER_DESC desc;
D3D_FEATURE_LEVEL levelUsed = D3D_FEATURE_LEVEL_9_3;
D3D_FEATURE_LEVEL levelUsed = D3D_FEATURE_LEVEL_10_0;
HRESULT hr = 0;
adpIdx = adapterIdx;
@ -444,9 +459,14 @@ void gs_device::InitDevice(uint32_t adapterIdx)
blog(LOG_INFO, "D3D11 loaded successfully, feature level used: %x",
(unsigned int)levelUsed);
/* adjust gpu thread priority */
/* prevent stalls sometimes seen in Present calls */
if (!increase_maximum_frame_latency(device)) {
blog(LOG_INFO, "DXGI increase maximum frame latency failed");
}
/* adjust gpu thread priority on non-intel GPUs */
#if USE_GPU_PRIORITY
if (!is_intel(adapterName) && !set_priority(device)) {
if (desc.VendorId != 0x8086 && !set_priority(device)) {
blog(LOG_INFO, "D3D11 GPU priority setup "
"failed (not admin?)");
}
@ -463,7 +483,7 @@ void gs_device::InitDevice(uint32_t adapterIdx)
}
/* Intel CopyResource is very slow with NV12 */
if (desc.VendorId == 0x8086) {
if (desc.VendorId == 0x8086 && IsOldIntelPlatform(desc.DeviceId)) {
return;
}
@ -925,6 +945,8 @@ static inline void LogD3DAdapters()
desc.DedicatedVideoMemory);
blog(LOG_INFO, "\t Shared VRAM: %u",
desc.SharedSystemMemory);
blog(LOG_INFO, "\t PCI ID: %x:%x", desc.VendorId,
desc.DeviceId);
/* driver version */
LARGE_INTEGER umd;
@ -1122,19 +1144,23 @@ gs_texture_t *device_cubetexture_create(gs_device_t *device, uint32_t size,
gs_texture_t *device_voltexture_create(gs_device_t *device, uint32_t width,
uint32_t height, uint32_t depth,
enum gs_color_format color_format,
uint32_t levels, const uint8_t **data,
uint32_t levels,
const uint8_t *const *data,
uint32_t flags)
{
/* TODO */
UNUSED_PARAMETER(device);
UNUSED_PARAMETER(width);
UNUSED_PARAMETER(height);
UNUSED_PARAMETER(depth);
UNUSED_PARAMETER(color_format);
UNUSED_PARAMETER(levels);
UNUSED_PARAMETER(data);
UNUSED_PARAMETER(flags);
return NULL;
gs_texture *texture = NULL;
try {
texture = new gs_texture_3d(device, width, height, depth,
color_format, levels, data, flags);
} catch (const HRError &error) {
blog(LOG_ERROR, "device_voltexture_create (D3D11): %s (%08lX)",
error.str, error.hr);
LogD3D11ErrorDetails(error, device);
} catch (const char *error) {
blog(LOG_ERROR, "device_voltexture_create (D3D11): %s", error);
}
return texture;
}
gs_zstencil_t *device_zstencil_create(gs_device_t *device, uint32_t width,
@ -1723,6 +1749,16 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst,
}
}
extern "C" void reset_duplicators(void);
void device_begin_frame(gs_device_t *device)
{
/* does nothing in D3D11 */
UNUSED_PARAMETER(device);
reset_duplicators();
}
void device_begin_scene(gs_device_t *device)
{
clear_textures(device);
@ -1853,12 +1889,9 @@ void device_present(gs_device_t *device)
}
}
extern "C" void reset_duplicators(void);
void device_flush(gs_device_t *device)
{
device->context->Flush();
reset_duplicators();
}
void device_set_cull_mode(gs_device_t *device, enum gs_cull_mode mode)
@ -2740,3 +2773,22 @@ device_stagesurface_create_nv12(gs_device_t *device, uint32_t width,
return surf;
}
extern "C" EXPORT void
device_register_loss_callbacks(gs_device_t *device,
const gs_device_loss *callbacks)
{
device->loss_callbacks.emplace_back(*callbacks);
}
extern "C" EXPORT void device_unregister_loss_callbacks(gs_device_t *device,
void *data)
{
for (auto iter = device->loss_callbacks.begin();
iter != device->loss_callbacks.end(); ++iter) {
if (iter->data == data) {
device->loss_callbacks.erase(iter);
break;
}
}
}

View file

@ -294,6 +294,7 @@ enum class gs_type {
gs_swap_chain,
gs_timer,
gs_timer_range,
gs_texture_3d,
};
struct gs_obj {
@ -458,10 +459,10 @@ struct gs_texture_2d : gs_texture {
D3D11_TEXTURE2D_DESC td = {};
void InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd);
void InitTexture(const uint8_t **data);
void InitTexture(const uint8_t *const *data);
void InitResourceView();
void InitRenderTargets();
void BackupTexture(const uint8_t **data);
void BackupTexture(const uint8_t *const *data);
void GetSharedHandle(IDXGIResource *dxgi_res);
void RebuildSharedTextureFallback();
@ -482,7 +483,7 @@ struct gs_texture_2d : gs_texture {
gs_texture_2d(gs_device_t *device, uint32_t width, uint32_t height,
gs_color_format colorFormat, uint32_t levels,
const uint8_t **data, uint32_t flags,
const uint8_t *const *data, uint32_t flags,
gs_texture_type type, bool gdiCompatible,
bool nv12 = false);
@ -491,6 +492,51 @@ struct gs_texture_2d : gs_texture {
gs_texture_2d(gs_device_t *device, uint32_t handle);
};
struct gs_texture_3d : gs_texture {
ComPtr<ID3D11Texture3D> texture;
uint32_t width = 0, height = 0, depth = 0;
uint32_t flags = 0;
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN;
bool isDynamic = false;
bool isShared = false;
bool genMipmaps = false;
uint32_t sharedHandle = GS_INVALID_HANDLE;
bool chroma = false;
bool acquired = false;
vector<vector<uint8_t>> data;
vector<D3D11_SUBRESOURCE_DATA> srd;
D3D11_TEXTURE3D_DESC td = {};
void InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd);
void InitTexture(const uint8_t *const *data);
void InitResourceView();
void BackupTexture(const uint8_t *const *data);
void GetSharedHandle(IDXGIResource *dxgi_res);
void RebuildSharedTextureFallback();
void Rebuild(ID3D11Device *dev);
void RebuildNV12_Y(ID3D11Device *dev);
void RebuildNV12_UV(ID3D11Device *dev);
inline void Release()
{
texture.Release();
shaderRes.Release();
}
inline gs_texture_3d() : gs_texture(GS_TEXTURE_3D, 0, GS_UNKNOWN) {}
gs_texture_3d(gs_device_t *device, uint32_t width, uint32_t height,
uint32_t depth, gs_color_format colorFormat,
uint32_t levels, const uint8_t *const *data,
uint32_t flags);
gs_texture_3d(gs_device_t *device, uint32_t handle);
};
struct gs_zstencil_buffer : gs_obj {
ComPtr<ID3D11Texture2D> texture;
ComPtr<ID3D11DepthStencilView> view;
@ -900,6 +946,7 @@ struct gs_device {
matrix4 curViewMatrix;
matrix4 curViewProjMatrix;
vector<gs_device_loss> loss_callbacks;
gs_obj *first_obj = nullptr;
void InitCompiler();

View file

@ -27,7 +27,7 @@ void gs_texture_2d::InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd)
size_t curTex = 0;
if (!actual_levels)
actual_levels = gs_get_total_levels(width, height);
actual_levels = gs_get_total_levels(width, height, 1);
rowSizeBytes /= 8;
@ -48,7 +48,7 @@ void gs_texture_2d::InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd)
}
}
void gs_texture_2d::BackupTexture(const uint8_t **data)
void gs_texture_2d::BackupTexture(const uint8_t *const *data)
{
this->data.resize(levels);
@ -66,8 +66,10 @@ void gs_texture_2d::BackupTexture(const uint8_t **data)
vector<uint8_t> &subData = this->data[i];
memcpy(&subData[0], data[i], texSize);
w /= 2;
h /= 2;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
}
@ -87,7 +89,7 @@ void gs_texture_2d::GetSharedHandle(IDXGIResource *dxgi_res)
}
}
void gs_texture_2d::InitTexture(const uint8_t **data)
void gs_texture_2d::InitTexture(const uint8_t *const *data)
{
HRESULT hr;
@ -226,7 +228,7 @@ void gs_texture_2d::InitRenderTargets()
gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width,
uint32_t height, gs_color_format colorFormat,
uint32_t levels, const uint8_t **data,
uint32_t levels, const uint8_t *const *data,
uint32_t flags_, gs_texture_type type,
bool gdiCompatible, bool nv12_)
: gs_texture(device, gs_type::gs_texture_2d, type, levels, colorFormat),

View file

@ -0,0 +1,226 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include <util/base.h>
#include "d3d11-subsystem.hpp"
void gs_texture_3d::InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd)
{
uint32_t rowSizeBits = width * gs_get_format_bpp(format);
uint32_t sliceSizeBytes = height * rowSizeBits / 8;
uint32_t actual_levels = levels;
if (!actual_levels)
actual_levels = gs_get_total_levels(width, height, depth);
uint32_t newRowSize = rowSizeBits / 8;
uint32_t newSlizeSize = sliceSizeBytes;
for (uint32_t level = 0; level < actual_levels; ++level) {
D3D11_SUBRESOURCE_DATA newSRD;
newSRD.pSysMem = data[level].data();
newSRD.SysMemPitch = newRowSize;
newSRD.SysMemSlicePitch = newSlizeSize;
srd.push_back(newSRD);
newRowSize /= 2;
newSlizeSize /= 4;
}
}
void gs_texture_3d::BackupTexture(const uint8_t *const *data)
{
this->data.resize(levels);
uint32_t w = width;
uint32_t h = height;
uint32_t d = depth;
const uint32_t bbp = gs_get_format_bpp(format);
for (uint32_t i = 0; i < levels; i++) {
if (!data[i])
break;
const uint32_t texSize = bbp * w * h * d / 8;
this->data[i].resize(texSize);
vector<uint8_t> &subData = this->data[i];
memcpy(&subData[0], data[i], texSize);
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
if (d > 1)
d /= 2;
}
}
void gs_texture_3d::GetSharedHandle(IDXGIResource *dxgi_res)
{
HANDLE handle;
HRESULT hr;
hr = dxgi_res->GetSharedHandle(&handle);
if (FAILED(hr)) {
blog(LOG_WARNING,
"GetSharedHandle: Failed to "
"get shared handle: %08lX",
hr);
} else {
sharedHandle = (uint32_t)(uintptr_t)handle;
}
}
void gs_texture_3d::InitTexture(const uint8_t *const *data)
{
HRESULT hr;
memset(&td, 0, sizeof(td));
td.Width = width;
td.Height = height;
td.Depth = depth;
td.MipLevels = genMipmaps ? 0 : levels;
td.Format = dxgiFormat;
td.BindFlags = D3D11_BIND_SHADER_RESOURCE;
td.CPUAccessFlags = isDynamic ? D3D11_CPU_ACCESS_WRITE : 0;
td.Usage = isDynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
if (type == GS_TEXTURE_CUBE)
td.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
if ((flags & GS_SHARED_KM_TEX) != 0)
td.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
else if ((flags & GS_SHARED_TEX) != 0)
td.MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
if (data) {
BackupTexture(data);
InitSRD(srd);
}
hr = device->device->CreateTexture3D(&td, data ? srd.data() : NULL,
texture.Assign());
if (FAILED(hr))
throw HRError("Failed to create 3D texture", hr);
if (isShared) {
ComPtr<IDXGIResource> dxgi_res;
texture->SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM);
hr = texture->QueryInterface(__uuidof(IDXGIResource),
(void **)&dxgi_res);
if (FAILED(hr)) {
blog(LOG_WARNING,
"InitTexture: Failed to query "
"interface: %08lX",
hr);
} else {
GetSharedHandle(dxgi_res);
if (flags & GS_SHARED_KM_TEX) {
ComPtr<IDXGIKeyedMutex> km;
hr = texture->QueryInterface(
__uuidof(IDXGIKeyedMutex),
(void **)&km);
if (FAILED(hr)) {
throw HRError("Failed to query "
"IDXGIKeyedMutex",
hr);
}
km->AcquireSync(0, INFINITE);
acquired = true;
}
}
}
}
void gs_texture_3d::InitResourceView()
{
HRESULT hr;
memset(&resourceDesc, 0, sizeof(resourceDesc));
resourceDesc.Format = dxgiFormat;
resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
resourceDesc.Texture3D.MostDetailedMip = 0;
resourceDesc.Texture3D.MipLevels = genMipmaps || !levels ? -1 : levels;
hr = device->device->CreateShaderResourceView(texture, &resourceDesc,
shaderRes.Assign());
if (FAILED(hr))
throw HRError("Failed to create resource view", hr);
}
#define SHARED_FLAGS (GS_SHARED_TEX | GS_SHARED_KM_TEX)
gs_texture_3d::gs_texture_3d(gs_device_t *device, uint32_t width,
uint32_t height, uint32_t depth,
gs_color_format colorFormat, uint32_t levels,
const uint8_t *const *data, uint32_t flags_)
: gs_texture(device, gs_type::gs_texture_3d, GS_TEXTURE_3D, levels,
colorFormat),
width(width),
height(height),
depth(depth),
flags(flags_),
dxgiFormat(ConvertGSTextureFormat(format)),
isDynamic((flags_ & GS_DYNAMIC) != 0),
isShared((flags_ & SHARED_FLAGS) != 0),
genMipmaps((flags_ & GS_BUILD_MIPMAPS) != 0),
sharedHandle(GS_INVALID_HANDLE)
{
InitTexture(data);
InitResourceView();
}
gs_texture_3d::gs_texture_3d(gs_device_t *device, uint32_t handle)
: gs_texture(device, gs_type::gs_texture_3d, GS_TEXTURE_3D),
isShared(true),
sharedHandle(handle)
{
HRESULT hr;
hr = device->device->OpenSharedResource((HANDLE)(uintptr_t)handle,
IID_PPV_ARGS(texture.Assign()));
if (FAILED(hr))
throw HRError("Failed to open shared 3D texture", hr);
texture->GetDesc(&td);
this->type = GS_TEXTURE_3D;
this->format = ConvertDXGITextureFormat(td.Format);
this->levels = 1;
this->device = device;
this->width = td.Width;
this->height = td.Height;
this->depth = td.Depth;
this->dxgiFormat = td.Format;
memset(&resourceDesc, 0, sizeof(resourceDesc));
resourceDesc.Format = td.Format;
resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
resourceDesc.Texture3D.MostDetailedMip = 0;
resourceDesc.Texture3D.MipLevels = 1;
hr = device->device->CreateShaderResourceView(texture, &resourceDesc,
shaderRes.Assign());
if (FAILED(hr))
throw HRError("Failed to create shader resource view", hr);
}

View file

@ -0,0 +1,322 @@
static bool IsOldIntelPlatform(uint32_t device_id)
{
switch (device_id) {
/*IVB*/
case 0x0152:
case 0x0156:
case 0x015A:
case 0x0162:
case 0x0166:
case 0x016A:
case 0x0172:
case 0x0176:
case 0x0182:
case 0x0186:
return true;
/* VLV */
case 0x0f30:
case 0x0f31:
case 0x0f32:
case 0x0f33:
case 0x0157:
case 0x0155:
return true;
/*HSW*/
case 0x0090:
case 0x0091:
case 0x0092:
case 0x0094:
case 0x0C02:
case 0x0C06:
case 0x0C12:
case 0x0C16:
case 0x0C22:
case 0x0C26:
case 0x0C0B:
case 0x0402:
case 0x0406:
case 0x040A:
case 0x040B:
case 0x040E:
case 0x0412:
case 0x0416:
case 0x041A:
case 0x041B:
case 0x041E:
case 0x0422:
case 0x0426:
case 0x042A:
case 0x042B:
case 0x042E:
case 0x0A02:
case 0x0A06:
case 0x0A0A:
case 0x0A0B:
case 0x0A0E:
case 0x0A12:
case 0x0A16:
case 0x0A1A:
case 0x0A1B:
case 0x0A1E:
case 0x0A22:
case 0x0A26:
case 0x0A2A:
case 0x0A2B:
case 0x0A2E:
return true;
/* CRW */
case 0x0D02:
case 0x0D06:
case 0x0D0A:
case 0x0D0B:
case 0x0D0E:
case 0x0D12:
case 0x0D16:
case 0x0D1A:
case 0x0D1B:
case 0x0D1E:
case 0x0D22:
case 0x0D26:
case 0x0D2A:
case 0x0D2B:
case 0x0D2E:
return true;
/* BDW */
case 0x1602:
case 0x1606:
case 0x160A:
case 0x160B:
case 0x160D:
case 0x160E:
case 0x1612:
case 0x1616:
case 0x161A:
case 0x161B:
case 0x161D:
case 0x161E:
case 0x1622:
case 0x1626:
case 0x162A:
case 0x162B:
case 0x162D:
case 0x162E:
case 0x1632:
case 0x1636:
case 0x163A:
case 0x163B:
case 0x163D:
case 0x163E:
case 0x0BD0:
case 0x0BD1:
case 0x0BD2:
case 0x0BD3:
case 0x0BD4:
return true;
/* CHT */
case 0x22b0:
case 0x22b1:
case 0x22b2:
case 0x22b3:
return true;
/* SKL */
case 0x0900:
case 0x0901:
case 0x0902:
case 0x0903:
case 0x0904:
case 0x1902:
case 0x1906:
case 0x190A:
case 0x190B:
case 0x190E:
case 0x1913:
case 0x1915:
case 0x1917:
case 0x1912:
case 0x1916:
case 0x191A:
case 0x191B:
case 0x191D:
case 0x191E:
case 0x1921:
case 0x1923:
case 0x1926:
case 0x1927:
case 0x192A:
case 0x192B:
case 0x192D:
case 0x1932:
case 0x193A:
case 0x193B:
case 0x193D:
case 0x9905:
return true;
/* GLK */
case 0x3184:
case 0x3185:
return true;
/* APL */
case 0x9906:
case 0x9907:
case 0x9908:
case 0x0A84:
case 0x0A85:
case 0x0A86:
case 0x0A87:
case 0x1A84:
case 0x1A85:
case 0x5A84:
case 0x5A85:
return true;
/* KBL */
case 0x5902:
case 0x5906:
case 0x5908:
case 0x590A:
case 0x590B:
case 0x590E:
case 0x5912:
case 0x5913:
case 0x5915:
case 0x5916:
case 0x5917:
case 0x591A:
case 0x591B:
case 0x591C:
case 0x591D:
case 0x591E:
case 0x5921:
case 0x5923:
case 0x5926:
case 0x5927:
case 0x592A:
case 0x592B:
case 0x5932:
case 0x593A:
case 0x593B:
case 0x593D:
case 0x87C0:
return true;
/* CFL */
case 0x3E04:
case 0x3E90:
case 0x3E91:
case 0x3E92:
case 0x3E93:
case 0x3E94:
case 0x3E96:
case 0x3E98:
case 0x3E99:
case 0x3E9A:
case 0x3E9C:
case 0x3E9B:
case 0x3EA5:
case 0x3EA6:
case 0x3EA7:
case 0x3EA8:
case 0x3EA9:
case 0x5B04:
case 0x87CA:
return true;
/* WHL */
case 0x3EA0:
case 0x3EA1:
case 0x3EA2:
case 0x3EA3:
case 0x3EA4:
return true;
/* CML */
case 0x9b21:
case 0x9baa:
case 0x9bab:
case 0x9bac:
case 0x9ba0:
case 0x9ba5:
case 0x9ba8:
case 0x9ba4:
case 0x9ba2:
case 0x9b41:
case 0x9bca:
case 0x9bcb:
case 0x9bcc:
case 0x9bc0:
case 0x9bc5:
case 0x9bc8:
case 0x9bc4:
case 0x9bc2:
case 0x9bc6:
case 0x9be6:
case 0x9bf6:
return true;
/* CNL */
case 0x0A01:
case 0x0A00:
case 0x0A05:
case 0x0A07:
case 0x5A40:
case 0x5A50:
case 0x5A60:
case 0x5A70:
case 0x5A41:
case 0x5A51:
case 0x5A61:
case 0x5A71:
case 0x5A42:
case 0x5A52:
case 0x5A62:
case 0x5A72:
case 0x5A43:
case 0x5A53:
case 0x5A63:
case 0x5A73:
case 0x5A45:
case 0x5A55:
case 0x5A65:
case 0x5A75:
case 0x5A46:
case 0x5A56:
case 0x5A66:
case 0x5A76:
case 0x5A47:
case 0x5A57:
case 0x5A67:
case 0x5A77:
case 0x5A58:
case 0x5A68:
case 0x5A78:
case 0x5A49:
case 0x5A59:
case 0x5A79:
case 0x5A4A:
case 0x5A5A:
case 0x5A6A:
case 0x5A7A:
case 0x5A6B:
case 0x5A4D:
case 0x5A5D:
case 0x5A44:
case 0x5A54:
case 0x5A64:
case 0x5A74:
case 0x5A4C:
case 0x5A5C:
return true;
/* ICL or later platforms */
default:
return false;
}
}