1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // D3D11FormatTablesTest:
7 // Tests to validate our D3D11 support tables match hardware support.
8 //
9
10 #include "common/debug.h"
11 #include "libANGLE/Context.h"
12 #include "libANGLE/angletypes.h"
13 #include "libANGLE/formatutils.h"
14 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
15 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
16 #include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
17 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
18 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
19 #include "test_utils/ANGLETest.h"
20 #include "test_utils/angle_test_instantiate.h"
21 #include "util/EGLWindow.h"
22
23 using namespace angle;
24
25 namespace
26 {
27
28 class D3D11FormatTablesTest : public ANGLETest
29 {};
30
31 // This test enumerates all GL formats - for each, it queries the D3D support for
32 // using it as a texture, a render target, and sampling from it in the shader. It
33 // checks this against our speed-optimized baked tables, and validates they would
34 // give the same result.
35 // TODO(jmadill): Find out why in 9_3, some format queries return an error.
36 // The error seems to appear for formats that are not supported on 9_3.
TEST_P(D3D11FormatTablesTest,TestFormatSupport)37 TEST_P(D3D11FormatTablesTest, TestFormatSupport)
38 {
39 ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer());
40
41 // Hack the angle!
42 gl::Context *context = static_cast<gl::Context *>(getEGLWindow()->getContext());
43 rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
44 rx::Renderer11 *renderer = context11->getRenderer();
45 const auto &textureCaps = renderer->getNativeTextureCaps();
46
47 ID3D11Device *device = renderer->getDevice();
48
49 const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
50 for (GLenum internalFormat : allFormats)
51 {
52 const rx::d3d11::Format &formatInfo =
53 rx::d3d11::Format::Get(internalFormat, renderer->getRenderer11DeviceCaps());
54 const auto &textureInfo = textureCaps.get(internalFormat);
55
56 // Bits for texturing
57 const gl::InternalFormat &internalFormatInfo =
58 gl::GetSizedInternalFormatInfo(internalFormat);
59
60 UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D;
61 if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0)
62 {
63 texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
64 if (GetParam().majorVersion > 2)
65 {
66 texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
67 }
68 }
69
70 UINT texSupport = 0;
71 bool texSuccess = SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &texSupport));
72 bool textureable = texSuccess && ((texSupport & texSupportMask) == texSupportMask);
73 EXPECT_EQ(textureable, textureInfo.texturable) << " for " << gl::FmtHex(internalFormat);
74
75 // Bits for mipmap auto-gen.
76 bool expectedMipGen = texSuccess && ((texSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
77 auto featureLevel = renderer->getRenderer11DeviceCaps().featureLevel;
78 const auto &dxgiSupport = rx::d3d11::GetDXGISupport(formatInfo.texFormat, featureLevel);
79 bool actualMipGen =
80 ((dxgiSupport.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
81 EXPECT_EQ(0u, dxgiSupport.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN)
82 << " for " << gl::FmtHex(internalFormat);
83 EXPECT_EQ(expectedMipGen, actualMipGen) << " for " << gl::FmtHex(internalFormat);
84
85 // Bits for filtering
86 UINT filterSupport = 0;
87 bool filterSuccess =
88 SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &filterSupport));
89 bool filterable =
90 filterSuccess && ((filterSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE) != 0);
91 EXPECT_EQ(filterable, textureInfo.filterable) << " for " << gl::FmtHex(internalFormat);
92
93 // Bits for renderable
94 bool renderable = false;
95 UINT renderSupport = 0u;
96 DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN;
97 if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
98 {
99 renderFormat = formatInfo.dsvFormat;
100 bool depthSuccess =
101 SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &renderSupport));
102 renderable =
103 depthSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0);
104 if (renderable)
105 {
106 EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.dsvFormat)
107 << " for " << gl::FmtHex(internalFormat);
108 }
109 }
110 else
111 {
112 renderFormat = formatInfo.rtvFormat;
113 bool rtSuccess =
114 SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &renderSupport));
115 renderable = rtSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0);
116 if (renderable)
117 {
118 EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.rtvFormat)
119 << " for " << gl::FmtHex(internalFormat);
120 }
121 }
122 EXPECT_EQ(renderable, textureInfo.textureAttachment)
123 << " for " << gl::FmtHex(internalFormat);
124 EXPECT_EQ(renderable, textureInfo.renderbuffer) << " for " << gl::FmtHex(internalFormat);
125 if (!textureInfo.sampleCounts.empty())
126 {
127 EXPECT_TRUE(renderable) << " for " << gl::FmtHex(internalFormat);
128 }
129
130 // Multisample counts
131 if (renderable)
132 {
133 if ((renderSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)
134 {
135 EXPECT_TRUE(!textureInfo.sampleCounts.empty());
136 for (unsigned int sampleCount = 1;
137 sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2)
138 {
139 UINT qualityCount = 0;
140 bool sampleSuccess = SUCCEEDED(device->CheckMultisampleQualityLevels(
141 renderFormat, sampleCount, &qualityCount));
142 GLuint expectedCount = (!sampleSuccess || qualityCount == 0) ? 0 : 1;
143 EXPECT_EQ(expectedCount, textureInfo.sampleCounts.count(sampleCount))
144 << " for " << gl::FmtHex(internalFormat);
145 }
146 }
147 else
148 {
149 EXPECT_TRUE(textureInfo.sampleCounts.empty())
150 << " for " << gl::FmtHex(internalFormat);
151 }
152 }
153 }
154 }
155
156 ANGLE_INSTANTIATE_TEST(D3D11FormatTablesTest,
157 ES2_D3D11_FL9_3(),
158 ES2_D3D11_FL10_0(),
159 ES2_D3D11_FL10_1(),
160 ES2_D3D11_FL11_0());
161
162 } // anonymous namespace
163