Commit 5d121e1e by Jamie Madill

Add generated tables to mirror D3D11 format support.

*re-land with fix for test build* These tables can save us on startup time. Instead of querying the tables, we can keep certain assumptions about texture formats because certain formats are guaranteed to be supported in various feature levels. Testing with angle_perftests indicates this patch series will save about 50% of the time we spend in Renderer11::initializeDevice. BUG=angleproject:1014 Change-Id: I5477eea3e8433d36119cd099fb0c08eea168489a Reviewed-on: https://chromium-review.googlesource.com/276758Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 00787935
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "libANGLE/renderer/d3d/d3d11/Trim11.h" #include "libANGLE/renderer/d3d/d3d11/Trim11.h"
#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" #include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "third_party/trace_event/trace_event.h" #include "third_party/trace_event/trace_event.h"
......
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// dxgi_support_table:
// Queries for DXGI support of various texture formats. Depends on DXGI
// version, D3D feature level, and is sometimes guaranteed or optional.
//
#include "common/platform.h"
namespace rx
{
namespace d3d11
{
struct DXGISupport
{
DXGISupport()
: alwaysSupportedFlags(0),
neverSupportedFlags(0),
optionallySupportedFlags(0)
{
}
DXGISupport(UINT alwaysSupportedIn, UINT neverSupportedIn, UINT optionallySupportedIn)
: alwaysSupportedFlags(alwaysSupportedIn),
neverSupportedFlags(neverSupportedIn),
optionallySupportedFlags(optionallySupportedIn)
{
}
UINT alwaysSupportedFlags;
UINT neverSupportedFlags;
UINT optionallySupportedFlags;
};
const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel);
} // namespace d3d11
} // namespace rx
#!/usr/bin/python
# Copyright 2015 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_dxgi_support_tables.py:
# Code generation for the DXGI support tables. Determines which formats
# are natively support in D3D10+.
#
# MSDN links:
# 10_0: https://msdn.microsoft.com/en-us/library/windows/desktop/cc627090.aspx
# 10_1: https://msdn.microsoft.com/en-us/library/windows/desktop/cc627091.aspx
# 11_0: https://msdn.microsoft.com/en-us/library/windows/desktop/ff471325.aspx
# 11_1: https://msdn.microsoft.com/en-us/library/windows/desktop/hh404483.aspx
import sys
import json
macro_prefix = 'F_'
template = """// GENERATED FILE - DO NOT EDIT. See dxgi_support_data.json.
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// dxgi_support_table:
// Queries for DXGI support of various texture formats. Depends on DXGI
// version, D3D feature level, and is sometimes guaranteed or optional.
//
#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
#include "common/debug.h"
namespace rx
{{
namespace d3d11
{{
#define {prefix}2D D3D11_FORMAT_SUPPORT_TEXTURE2D
#define {prefix}3D D3D11_FORMAT_SUPPORT_TEXTURE3D
#define {prefix}CUBE D3D11_FORMAT_SUPPORT_TEXTURECUBE
#define {prefix}SAMPLE D3D11_FORMAT_SUPPORT_SHADER_SAMPLE
#define {prefix}RT D3D11_FORMAT_SUPPORT_RENDER_TARGET
#define {prefix}MS D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET
#define {prefix}DS D3D11_FORMAT_SUPPORT_DEPTH_STENCIL
namespace
{{
const DXGISupport &GetDefaultSupport()
{{
static UINT AllSupportFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D |
D3D11_FORMAT_SUPPORT_TEXTURE3D |
D3D11_FORMAT_SUPPORT_TEXTURECUBE |
D3D11_FORMAT_SUPPORT_SHADER_SAMPLE |
D3D11_FORMAT_SUPPORT_RENDER_TARGET |
D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET |
D3D11_FORMAT_SUPPORT_DEPTH_STENCIL;
static const DXGISupport defaultSupport(0, 0, AllSupportFlags);
return defaultSupport;
}}
const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat)
{{
switch (dxgiFormat)
{{
{table_data_10_0}
default:
UNREACHABLE();
return GetDefaultSupport();
}}
}}
const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat)
{{
switch (dxgiFormat)
{{
{table_data_10_1}
default:
UNREACHABLE();
return GetDefaultSupport();
}}
}}
const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat)
{{
switch (dxgiFormat)
{{
{table_data_11_0}
default:
UNREACHABLE();
return GetDefaultSupport();
}}
}}
}}
#undef {prefix}2D
#undef {prefix}3D
#undef {prefix}CUBE
#undef {prefix}SAMPLE
#undef {prefix}RT
#undef {prefix}MS
#undef {prefix}DS
const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel)
{{
switch (featureLevel)
{{
case D3D_FEATURE_LEVEL_10_0:
return GetDXGISupport_10_0(dxgiFormat);
case D3D_FEATURE_LEVEL_10_1:
return GetDXGISupport_10_1(dxgiFormat);
case D3D_FEATURE_LEVEL_11_0:
return GetDXGISupport_11_0(dxgiFormat);
default:
return GetDefaultSupport();
}}
}}
}} // namespace d3d11
}} // namespace rx
"""
table_init = ""
def do_format(format_data):
table_data = {'10_0': '', '10_1': '', '11_0': ''}
json_flag_to_d3d = {
'texture2D': macro_prefix + '2D',
'texture3D': macro_prefix + '3D',
'textureCube': macro_prefix + 'CUBE',
'shaderSample': macro_prefix + 'SAMPLE',
'renderTarget': macro_prefix + 'RT',
'multisampleRT': macro_prefix + 'MS',
'depthStencil': macro_prefix + 'DS'
}
for format_name, format_support in sorted(format_data.iteritems()):
always_supported = []
never_supported = []
optionally_supported = []
for json_flag, support in format_support.iteritems():
d3d_flag = json_flag_to_d3d[json_flag]
# TODO(jmadill): process different support
if support != 'check':
print("Data specification error: " + support)
sys.exit(1)
optionally_supported += [d3d_flag]
for feature_level in ['10_0', '10_1', '11_0']:
always = ' | '.join(sorted(always_supported))
never = ' | '.join(sorted(never_supported))
optional = ' | '.join(sorted(optionally_supported))
if not always: always = '0'
if not never: never = '0'
if not optional: optional = '0'
table_data[feature_level] += ' case ' + format_name + ':\n'
table_data[feature_level] += ' {\n'
table_data[feature_level] += ' static const DXGISupport info(' + always + ', ' + never + ', ' + optional + ');\n'
table_data[feature_level] += ' return info;\n'
table_data[feature_level] += ' }\n'
return table_data
def join_table_data(table_data_1, table_data_2):
return {'10_0': table_data_1['10_0'] + table_data_2['10_0'],
'10_1': table_data_1['10_1'] + table_data_2['10_1'],
'11_0': table_data_1['11_0'] + table_data_2['11_0']}
with open('dxgi_support_data.json') as dxgi_file:
file_data = dxgi_file.read()
dxgi_file.close()
json_data = json.loads(file_data)
table_data = {'10_0': '', '10_1': '', '11_0': ''}
for format_data in json_data:
table_data = join_table_data(table_data, do_format(format_data))
out_data = template.format(prefix=macro_prefix,
table_data_10_0=table_data['10_0'],
table_data_10_1=table_data['10_1'],
table_data_11_0=table_data['11_0'])
with open('dxgi_support_table.cpp', 'wt') as out_file:
out_file.write(out_data)
out_file.close()
...@@ -8,19 +8,20 @@ ...@@ -8,19 +8,20 @@
// specific to the D3D11 renderer. // specific to the D3D11 renderer.
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/Workarounds.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/Program.h"
#include "libANGLE/Framebuffer.h"
#include "common/debug.h"
#include <algorithm> #include <algorithm>
#include "common/debug.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/Program.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/Workarounds.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
namespace rx namespace rx
{ {
...@@ -229,6 +230,52 @@ D3D11_QUERY ConvertQueryType(GLenum queryType) ...@@ -229,6 +230,52 @@ D3D11_QUERY ConvertQueryType(GLenum queryType)
namespace d3d11_gl namespace d3d11_gl
{ {
namespace
{
// Helper functor for querying DXGI support. Saves passing the parameters repeatedly.
class DXGISupportHelper : angle::NonCopyable
{
public:
DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel)
: mDevice(device),
mFeatureLevel(featureLevel)
{
}
bool query(DXGI_FORMAT dxgiFormat, UINT supportMask)
{
if (dxgiFormat == DXGI_FORMAT_UNKNOWN)
return false;
auto dxgiSupport = d3d11::GetDXGISupport(dxgiFormat, mFeatureLevel);
UINT supportedBits = dxgiSupport.alwaysSupportedFlags;
if ((dxgiSupport.optionallySupportedFlags & supportMask) != 0)
{
UINT formatSupport;
if (SUCCEEDED(mDevice->CheckFormatSupport(dxgiFormat, &formatSupport)))
{
supportedBits |= (formatSupport & supportMask);
}
else
{
// TODO(jmadill): find out why we fail this call sometimes in FL9_3
// ERR("Error checking format support for format 0x%x", dxgiFormat);
}
}
return ((supportedBits & supportMask) == supportMask);
}
private:
ID3D11Device *mDevice;
D3D_FEATURE_LEVEL mFeatureLevel;
};
} // anonymous namespace
GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel) GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel)
{ {
switch (featureLevel) switch (featureLevel)
...@@ -250,29 +297,28 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum ...@@ -250,29 +297,28 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum
{ {
gl::TextureCaps textureCaps; gl::TextureCaps textureCaps;
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel);
const d3d11::TextureFormat &formatInfo =
d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps);
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
UINT formatSupport; UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D;
if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport))) if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0)
{ {
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0) if (maxClientVersion > 2)
{ {
textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0); texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
}
else
{
UINT formatSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
if (maxClientVersion > 2)
{
formatSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
}
textureCaps.texturable = ((formatSupport & formatSupportMask) == formatSupportMask);
} }
} }
if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) && textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask);
((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)) textureCaps.filterable = support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE);
textureCaps.renderable = (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) ||
(support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL));
if (support.query(formatInfo.renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
{ {
for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2) for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2)
{ {
...@@ -285,13 +331,6 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum ...@@ -285,13 +331,6 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum
} }
} }
textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) &&
((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0;
textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) &&
((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) ||
(SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) &&
((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0));
return textureCaps; return textureCaps;
} }
......
...@@ -275,6 +275,8 @@ ...@@ -275,6 +275,8 @@
'libANGLE/renderer/d3d/d3d11/copyvertex.inl', 'libANGLE/renderer/d3d/d3d11/copyvertex.inl',
'libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp', 'libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp',
'libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h', 'libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h',
'libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp',
'libANGLE/renderer/d3d/d3d11/dxgi_support_table.h',
'libANGLE/renderer/d3d/d3d11/Fence11.cpp', 'libANGLE/renderer/d3d/d3d11/Fence11.cpp',
'libANGLE/renderer/d3d/d3d11/Fence11.h', 'libANGLE/renderer/d3d/d3d11/Fence11.h',
'libANGLE/renderer/d3d/d3d11/formatutils11.cpp', 'libANGLE/renderer/d3d/d3d11/formatutils11.cpp',
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
], ],
'angle_end2end_tests_win_sources': 'angle_end2end_tests_win_sources':
[ [
'<(angle_path)/src/tests/gl_tests/D3D11FormatTablesTest.cpp',
'<(angle_path)/src/tests/gl_tests/QueryDisplayAttribTest.cpp', '<(angle_path)/src/tests/gl_tests/QueryDisplayAttribTest.cpp',
# TODO(cwallez) for Linux, requires a portable implementation of threads # TODO(cwallez) for Linux, requires a portable implementation of threads
'<(angle_path)/src/tests/egl_tests/EGLThreadTest.cpp', '<(angle_path)/src/tests/egl_tests/EGLThreadTest.cpp',
......
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// D3D11FormatTablesTest:
// Tests to validate our D3D11 support tables match hardware support.
//
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_instantiate.h"
using namespace angle;
namespace
{
class D3D11FormatTablesTest : public ANGLETest
{
};
// This test enumerates all GL formats - for each, it queries the D3D support for
// using it as a texture, a render target, and sampling from it in the shader. It
// checks this against our speed-optimized baked tables, and validates they would
// give the same result.
// TODO(jmadill): Find out why in 9_3, some format queries return an error
TEST_P(D3D11FormatTablesTest, TestFormatSupport)
{
ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer());
// Hack the angle!
gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
rx::Renderer11 *renderer = rx::GetAs<rx::Renderer11>(context->getRenderer());
const auto &textureCaps = renderer->getRendererTextureCaps();
ID3D11Device *device = renderer->getDevice();
const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
for (GLenum internalFormat : allFormats)
{
const rx::d3d11::TextureFormat &formatInfo =
rx::d3d11::GetTextureFormatInfo(internalFormat, renderer->getRenderer11DeviceCaps());
const auto &textureInfo = textureCaps.get(internalFormat);
// Bits for texturing
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D;
if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0)
{
texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
if (GetParam().majorVersion > 2)
{
texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
}
}
UINT texSupport;
bool texSuccess = SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &texSupport));
bool textureable = texSuccess && ((texSupport & texSupportMask) == texSupportMask);
EXPECT_EQ(textureable, textureInfo.texturable);
// Bits for filtering
UINT filterSupport;
bool filterSuccess = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &filterSupport));
bool filterable = filterSuccess && ((filterSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE) != 0);
EXPECT_EQ(filterable, textureInfo.filterable);
// Bits for renderable
bool renderable = false;
if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
{
UINT depthSupport;
bool depthSuccess = SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &depthSupport));
renderable = depthSuccess && ((depthSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0);
}
else
{
UINT rtSupport;
bool rtSuccess = SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &rtSupport));
renderable = rtSuccess && ((rtSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0);
}
EXPECT_EQ(renderable, textureInfo.renderable);
// Multisample counts
UINT renderSupport = false;
bool renderSuccess = SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &renderSupport));
if (renderSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0))
{
EXPECT_TRUE(!textureInfo.sampleCounts.empty());
for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2)
{
UINT qualityCount = 0;
bool sampleSuccess = SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount));
GLuint expectedCount = (!sampleSuccess || qualityCount == 0) ? 0 : 1;
EXPECT_EQ(expectedCount, textureInfo.sampleCounts.count(sampleCount));
}
}
else
{
EXPECT_TRUE(textureInfo.sampleCounts.empty());
}
}
}
ANGLE_INSTANTIATE_TEST(D3D11FormatTablesTest,
ES2_D3D11_FL9_3(),
ES2_D3D11_FL10_0(),
ES2_D3D11_FL10_1(),
ES2_D3D11_FL11_0());
} // anonymous namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment