Check FP16 support on D3D backend

True FP16 is only supported in DXC through Shader Model 6.2, also
check the value of the Native16BitShaderOpsSupported member of
D3D12_FEATURE_DATA_D3D12_OPTIONS4 to view whether hardware actually
supports FP16 operations.

BUG=dawn:426
TEST=dawn_end2end_tests

Change-Id: If675f7ba650cb1bd8c792928b70619b9ccda048a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23243
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Xinghua Cao <xinghua.cao@intel.com>
This commit is contained in:
Xinghua Cao 2020-07-06 08:28:00 +00:00 committed by Commit Bot service account
parent 80f927d763
commit db34c78910
4 changed files with 97 additions and 25 deletions

View File

@ -102,6 +102,9 @@ namespace dawn_native { namespace d3d12 {
mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
mSupportedExtensions.EnableExtension(Extension::PipelineStatisticsQuery);
mSupportedExtensions.EnableExtension(Extension::TimestampQuery);
if (mDeviceInfo.supportsShaderFloat16 && GetBackend()->GetFunctions()->IsDXCAvailable()) {
mSupportedExtensions.EnableExtension(Extension::ShaderFloat16);
}
}
MaybeError Adapter::InitializeDebugLayerFilters() {

View File

@ -59,6 +59,63 @@ namespace dawn_native { namespace d3d12 {
}
}
return info;
D3D12_FEATURE_DATA_SHADER_MODEL knownShaderModels[] = {{D3D_SHADER_MODEL_6_2},
{D3D_SHADER_MODEL_6_1},
{D3D_SHADER_MODEL_6_0},
{D3D_SHADER_MODEL_5_1}};
for (D3D12_FEATURE_DATA_SHADER_MODEL shaderModel : knownShaderModels) {
if (SUCCEEDED(adapter.GetDevice()->CheckFeatureSupport(
D3D12_FEATURE_SHADER_MODEL, &shaderModel, sizeof(shaderModel)))) {
if (shaderModel.HighestShaderModel < D3D_SHADER_MODEL_5_1) {
return DAWN_INTERNAL_ERROR(
"Driver could not support Shader Model 5.1 or higher");
}
switch (shaderModel.HighestShaderModel) {
case D3D_SHADER_MODEL_6_2: {
info.shaderModel = 62;
info.shaderProfiles[SingleShaderStage::Vertex] = L"vs_6_2";
info.shaderProfiles[SingleShaderStage::Fragment] = L"ps_6_2";
info.shaderProfiles[SingleShaderStage::Compute] = L"cs_6_2";
D3D12_FEATURE_DATA_D3D12_OPTIONS4 featureData4 = {};
if (SUCCEEDED(adapter.GetDevice()->CheckFeatureSupport(
D3D12_FEATURE_D3D12_OPTIONS4, &featureData4,
sizeof(featureData4)))) {
info.supportsShaderFloat16 =
shaderModel.HighestShaderModel >= D3D_SHADER_MODEL_6_2 &&
featureData4.Native16BitShaderOpsSupported;
}
break;
}
case D3D_SHADER_MODEL_6_1: {
info.shaderModel = 61;
info.shaderProfiles[SingleShaderStage::Vertex] = L"vs_6_1";
info.shaderProfiles[SingleShaderStage::Fragment] = L"ps_6_1";
info.shaderProfiles[SingleShaderStage::Compute] = L"cs_6_1";
break;
}
case D3D_SHADER_MODEL_6_0: {
info.shaderModel = 60;
info.shaderProfiles[SingleShaderStage::Vertex] = L"vs_6_0";
info.shaderProfiles[SingleShaderStage::Fragment] = L"ps_6_0";
info.shaderProfiles[SingleShaderStage::Compute] = L"cs_6_0";
break;
}
default: {
info.shaderModel = 51;
info.shaderProfiles[SingleShaderStage::Vertex] = L"vs_5_1";
info.shaderProfiles[SingleShaderStage::Fragment] = L"ps_5_1";
info.shaderProfiles[SingleShaderStage::Compute] = L"cs_5_1";
break;
}
}
// Successfully find the maximum supported shader model.
break;
}
}
return std::move(info);
}
}} // namespace dawn_native::d3d12

View File

@ -16,6 +16,7 @@
#define DAWNNATIVE_D3D12_D3D12INFO_H_
#include "dawn_native/Error.h"
#include "dawn_native/PerStage.h"
#include "dawn_native/d3d12/d3d12_platform.h"
namespace dawn_native { namespace d3d12 {
@ -26,6 +27,11 @@ namespace dawn_native { namespace d3d12 {
bool isUMA;
uint32_t resourceHeapTier;
bool supportsRenderPass;
bool supportsShaderFloat16;
// shaderModel indicates the maximum supported shader model, for example, the value 62
// indicates that current driver supports the maximum shader model is D3D_SHADER_MODEL_6_2.
uint32_t shaderModel;
PerStage<std::wstring> shaderProfiles;
};
ResultOrError<D3D12DeviceInfo> GatherDeviceInfo(const Adapter& adapter);

View File

@ -31,7 +31,7 @@
namespace dawn_native { namespace d3d12 {
namespace {
std::vector<const wchar_t*> GetDXCArguments(uint32_t compileFlags) {
std::vector<const wchar_t*> GetDXCArguments(uint32_t compileFlags, bool enable16BitTypes) {
std::vector<const wchar_t*> arguments;
if (compileFlags & D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY) {
arguments.push_back(L"/Gec");
@ -70,9 +70,15 @@ namespace dawn_native { namespace d3d12 {
if (compileFlags & D3DCOMPILE_RESOURCES_MAY_ALIAS) {
arguments.push_back(L"/res_may_alias");
}
if (enable16BitTypes) {
// enable-16bit-types are only allowed in -HV 2018 (default)
arguments.push_back(L"/enable-16bit-types");
} else {
// Enable FXC backward compatibility by setting the language version to 2016
arguments.push_back(L"-HV");
arguments.push_back(L"2016");
}
return arguments;
}
@ -98,7 +104,12 @@ namespace dawn_native { namespace d3d12 {
shaderc_spvc::CompileOptions options = GetCompileOptions();
options.SetForceZeroInitializedVariables(true);
if (GetDevice()->IsExtensionEnabled(Extension::ShaderFloat16)) {
options.SetHLSLShaderModel(ToBackend(GetDevice())->GetDeviceInfo().shaderModel);
options.SetHLSLEnable16BitTypes(true);
} else {
options.SetHLSLShaderModel(51);
}
// PointCoord and PointSize are not supported in HLSL
// TODO (hao.x.li@intel.com): The point_coord_compat and point_size_compat are
// required temporarily for https://bugs.chromium.org/p/dawn/issues/detail?id=146,
@ -138,7 +149,12 @@ namespace dawn_native { namespace d3d12 {
options_glsl.force_zero_initialized_variables = true;
spirv_cross::CompilerHLSL::Options options_hlsl;
if (GetDevice()->IsExtensionEnabled(Extension::ShaderFloat16)) {
options_hlsl.shader_model = ToBackend(GetDevice())->GetDeviceInfo().shaderModel;
options_hlsl.enable_16bit_types = true;
} else {
options_hlsl.shader_model = 51;
}
// PointCoord and PointSize are not supported in HLSL
// TODO (hao.x.li@intel.com): The point_coord_compat and point_size_compat are
// required temporarily for https://bugs.chromium.org/p/dawn/issues/detail?id=146,
@ -210,19 +226,6 @@ namespace dawn_native { namespace d3d12 {
const std::string& hlslSource,
const char* entryPoint,
uint32_t compileFlags) {
const wchar_t* targetProfile = nullptr;
switch (stage) {
case SingleShaderStage::Vertex:
targetProfile = L"vs_6_0";
break;
case SingleShaderStage::Fragment:
targetProfile = L"ps_6_0";
break;
case SingleShaderStage::Compute:
targetProfile = L"cs_6_0";
break;
}
IDxcLibrary* dxcLibrary;
DAWN_TRY_ASSIGN(dxcLibrary, ToBackend(GetDevice())->GetOrCreateDxcLibrary());
@ -237,11 +240,14 @@ namespace dawn_native { namespace d3d12 {
std::wstring entryPointW;
DAWN_TRY_ASSIGN(entryPointW, ConvertStringToWstring(entryPoint));
std::vector<const wchar_t*> arguments = GetDXCArguments(compileFlags);
std::vector<const wchar_t*> arguments = GetDXCArguments(
compileFlags, GetDevice()->IsExtensionEnabled(Extension::ShaderFloat16));
ComPtr<IDxcOperationResult> result;
DAWN_TRY(CheckHRESULT(
dxcCompiler->Compile(sourceBlob.Get(), nullptr, entryPointW.c_str(), targetProfile,
DAWN_TRY(
CheckHRESULT(dxcCompiler->Compile(
sourceBlob.Get(), nullptr, entryPointW.c_str(),
ToBackend(GetDevice())->GetDeviceInfo().shaderProfiles[stage].c_str(),
arguments.data(), arguments.size(), nullptr, 0, nullptr, &result),
"DXC compile"));