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 "libANGLE/angletypes.h"
11 #include "libANGLE/Context.h"
12 #include "libANGLE/formatutils.h"
13 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
14 #include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
15 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
16 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
17 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
18 #include "test_utils/angle_test_instantiate.h"
19 #include "test_utils/ANGLETest.h"
20 
21 using namespace angle;
22 
23 namespace
24 {
25 
26 class D3D11FormatTablesTest : public ANGLETest
27 {
28 
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 = reinterpret_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 = gl::GetInternalFormatInfo(internalFormat);
58 
59         UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D;
60         if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0)
61         {
62             texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
63             if (GetParam().majorVersion > 2)
64             {
65                 texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
66             }
67         }
68 
69         UINT texSupport  = 0;
70         bool texSuccess  = SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &texSupport));
71         bool textureable = texSuccess && ((texSupport & texSupportMask) == texSupportMask);
72         EXPECT_EQ(textureable, textureInfo.texturable);
73 
74         // Bits for mipmap auto-gen.
75         bool expectedMipGen = texSuccess && ((texSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
76         auto featureLevel   = renderer->getRenderer11DeviceCaps().featureLevel;
77         const auto &dxgiSupport = rx::d3d11::GetDXGISupport(formatInfo.texFormat, featureLevel);
78         bool actualMipGen =
79             ((dxgiSupport.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
80         EXPECT_EQ(0u, dxgiSupport.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN);
81         EXPECT_EQ(expectedMipGen, actualMipGen);
82 
83         // Bits for filtering
84         UINT filterSupport = 0;
85         bool filterSuccess =
86             SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &filterSupport));
87         bool filterable = filterSuccess && ((filterSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE) != 0);
88         EXPECT_EQ(filterable, textureInfo.filterable);
89 
90         // Bits for renderable
91         bool renderable = false;
92         UINT renderSupport       = 0u;
93         DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN;
94         if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
95         {
96             renderFormat = formatInfo.dsvFormat;
97             bool depthSuccess =
98                 SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &renderSupport));
99             renderable =
100                 depthSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0);
101             if (renderable)
102             {
103                 EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.dsvFormat);
104             }
105         }
106         else
107         {
108             renderFormat = formatInfo.rtvFormat;
109             bool rtSuccess =
110                 SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &renderSupport));
111             renderable = rtSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0);
112             if (renderable)
113             {
114                 EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.rtvFormat);
115             }
116         }
117         EXPECT_EQ(renderable, textureInfo.renderable);
118         if (!textureInfo.sampleCounts.empty())
119         {
120             EXPECT_TRUE(renderable);
121         }
122 
123         // Multisample counts
124         if (renderable)
125         {
126             if ((renderSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)
127             {
128                 EXPECT_TRUE(!textureInfo.sampleCounts.empty());
129                 for (unsigned int sampleCount = 1;
130                      sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2)
131                 {
132                     UINT qualityCount  = 0;
133                     bool sampleSuccess = SUCCEEDED(device->CheckMultisampleQualityLevels(
134                         renderFormat, sampleCount, &qualityCount));
135                     GLuint expectedCount = (!sampleSuccess || qualityCount == 0) ? 0 : 1;
136                     EXPECT_EQ(expectedCount, textureInfo.sampleCounts.count(sampleCount));
137                 }
138             }
139             else
140             {
141                 EXPECT_TRUE(textureInfo.sampleCounts.empty());
142             }
143         }
144     }
145 }
146 
147 ANGLE_INSTANTIATE_TEST(D3D11FormatTablesTest,
148                        ES2_D3D11_FL9_3(),
149                        ES2_D3D11_FL10_0(),
150                        ES2_D3D11_FL10_1(),
151                        ES2_D3D11_FL11_0());
152 
153 } // anonymous namespace
154