• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/formatutils11.h"
17 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
18 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
19 #include "libANGLE/renderer/dxgi_support_table.h"
20 #include "test_utils/ANGLETest.h"
21 #include "test_utils/angle_test_instantiate.h"
22 #include "util/EGLWindow.h"
23 
24 using namespace angle;
25 
26 namespace
27 {
28 
29 class D3D11FormatTablesTest : public ANGLETest
30 {};
31 
32 // This test enumerates all GL formats - for each, it queries the D3D support for
33 // using it as a texture, a render target, and sampling from it in the shader. It
34 // checks this against our speed-optimized baked tables, and validates they would
35 // give the same result.
36 // TODO(jmadill): Find out why in 9_3, some format queries return an error.
37 // The error seems to appear for formats that are not supported on 9_3.
TEST_P(D3D11FormatTablesTest,TestFormatSupport)38 TEST_P(D3D11FormatTablesTest, TestFormatSupport)
39 {
40     ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer());
41 
42     // Hack the angle!
43     gl::Context *context     = static_cast<gl::Context *>(getEGLWindow()->getContext());
44     rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
45     rx::Renderer11 *renderer = context11->getRenderer();
46     const auto &textureCaps  = renderer->getNativeTextureCaps();
47 
48     ID3D11Device *device = renderer->getDevice();
49 
50     const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
51     for (GLenum internalFormat : allFormats)
52     {
53         const rx::d3d11::Format &formatInfo =
54             rx::d3d11::Format::Get(internalFormat, renderer->getRenderer11DeviceCaps());
55         const auto &textureInfo = textureCaps.get(internalFormat);
56 
57         // Bits for texturing
58         const gl::InternalFormat &internalFormatInfo =
59             gl::GetSizedInternalFormatInfo(internalFormat);
60 
61         UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D;
62         if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0)
63         {
64             texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
65             if (GetParam().majorVersion > 2)
66             {
67                 texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
68             }
69         }
70 
71         UINT texSupport  = 0;
72         bool texSuccess  = SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &texSupport));
73         bool textureable = texSuccess && ((texSupport & texSupportMask) == texSupportMask);
74         EXPECT_EQ(textureable, textureInfo.texturable) << " for " << gl::FmtHex(internalFormat);
75 
76         // Bits for mipmap auto-gen.
77         bool expectedMipGen = texSuccess && ((texSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
78         auto featureLevel   = renderer->getRenderer11DeviceCaps().featureLevel;
79         const auto &dxgiSupport = rx::d3d11::GetDXGISupport(formatInfo.texFormat, featureLevel);
80         bool actualMipGen =
81             ((dxgiSupport.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
82         EXPECT_EQ(0u, dxgiSupport.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN)
83             << " for " << gl::FmtHex(internalFormat);
84         EXPECT_EQ(expectedMipGen, actualMipGen) << " for " << gl::FmtHex(internalFormat);
85 
86         // Bits for filtering
87         UINT filterSupport = 0;
88         bool filterSuccess =
89             SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &filterSupport));
90         bool filterable =
91             filterSuccess && ((filterSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE) != 0);
92         EXPECT_EQ(filterable, textureInfo.filterable) << " for " << gl::FmtHex(internalFormat);
93 
94         // Bits for renderable
95         bool renderable          = false;
96         UINT renderSupport       = 0u;
97         DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN;
98         if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
99         {
100             renderFormat = formatInfo.dsvFormat;
101             bool depthSuccess =
102                 SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &renderSupport));
103             renderable =
104                 depthSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0);
105             if (renderable)
106             {
107                 EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.dsvFormat)
108                     << " for " << gl::FmtHex(internalFormat);
109             }
110         }
111         else
112         {
113             renderFormat = formatInfo.rtvFormat;
114             bool rtSuccess =
115                 SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &renderSupport));
116             renderable = rtSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0);
117             if (renderable)
118             {
119                 EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.rtvFormat)
120                     << " for " << gl::FmtHex(internalFormat);
121             }
122         }
123         EXPECT_EQ(renderable, textureInfo.textureAttachment)
124             << " for " << gl::FmtHex(internalFormat);
125         EXPECT_EQ(renderable, textureInfo.renderbuffer) << " for " << gl::FmtHex(internalFormat);
126         if (!textureInfo.sampleCounts.empty())
127         {
128             EXPECT_TRUE(renderable) << " for " << gl::FmtHex(internalFormat);
129         }
130 
131         // Multisample counts
132         if (renderable)
133         {
134             if ((renderSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)
135             {
136                 EXPECT_TRUE(!textureInfo.sampleCounts.empty());
137                 for (unsigned int sampleCount = 1;
138                      sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2)
139                 {
140                     UINT qualityCount    = 0;
141                     bool sampleSuccess   = SUCCEEDED(device->CheckMultisampleQualityLevels(
142                         renderFormat, sampleCount, &qualityCount));
143                     GLuint expectedCount = (!sampleSuccess || qualityCount == 0) ? 0 : 1;
144                     EXPECT_EQ(expectedCount, textureInfo.sampleCounts.count(sampleCount))
145                         << " for " << gl::FmtHex(internalFormat);
146                 }
147             }
148             else
149             {
150                 EXPECT_TRUE(textureInfo.sampleCounts.empty())
151                     << " for " << gl::FmtHex(internalFormat);
152             }
153         }
154     }
155 }
156 
157 // This test validates that all DXGI_FORMATs can be potentially resized without crashes.
TEST_P(D3D11FormatTablesTest,TestFormatMakeValidSize)158 TEST_P(D3D11FormatTablesTest, TestFormatMakeValidSize)
159 {
160     gl::Context *context     = static_cast<gl::Context *>(getEGLWindow()->getContext());
161     rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
162     rx::Renderer11 *renderer = context11->getRenderer();
163 
164     const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
165     for (GLenum internalFormat : allFormats)
166     {
167         const rx::d3d11::Format &formatInfo =
168             rx::d3d11::Format::Get(internalFormat, renderer->getRenderer11DeviceCaps());
169 
170         std::array<bool, 2> isImages = {false, true};
171         for (auto &image : isImages)
172         {
173             int reqWidth  = 32;
174             int reqHeight = 32;
175             int level     = 0;
176 
177             rx::d3d11::MakeValidSize(image, formatInfo.texFormat, &reqWidth, &reqHeight, &level);
178         }
179     }
180 }
181 
182 ANGLE_INSTANTIATE_TEST(D3D11FormatTablesTest,
183                        ES2_D3D11_FL10_0(),
184                        ES2_D3D11_FL10_1(),
185                        ES2_D3D11_FL11_0());
186 
187 }  // anonymous namespace
188