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