summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/D3D11FormatTablesTest.cpp
blob: e407d1190dadbfdd84c50564fefd6a5d47f2291a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// 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/Context.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/d3d11/Context11.h"
#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include "test_utils/angle_test_instantiate.h"
#include "test_utils/ANGLETest.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.
// The error seems to appear for formats that are not supported on 9_3.
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::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
    rx::Renderer11 *renderer = context11->getRenderer();
    const auto &textureCaps  = renderer->getNativeTextureCaps();

    ID3D11Device *device = renderer->getDevice();

    const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
    for (GLenum internalFormat : allFormats)
    {
        const rx::d3d11::Format &formatInfo =
            rx::d3d11::Format::Get(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  = 0;
        bool texSuccess  = SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &texSupport));
        bool textureable = texSuccess && ((texSupport & texSupportMask) == texSupportMask);
        EXPECT_EQ(textureable, textureInfo.texturable);

        // Bits for mipmap auto-gen.
        bool expectedMipGen = texSuccess && ((texSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
        auto featureLevel   = renderer->getRenderer11DeviceCaps().featureLevel;
        const auto &dxgiSupport = rx::d3d11::GetDXGISupport(formatInfo.texFormat, featureLevel);
        bool actualMipGen =
            ((dxgiSupport.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
        EXPECT_EQ(0u, dxgiSupport.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN);
        EXPECT_EQ(expectedMipGen, actualMipGen);

        // Bits for filtering
        UINT filterSupport = 0;
        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;
        UINT renderSupport       = 0u;
        DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN;
        if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
        {
            renderFormat = formatInfo.dsvFormat;
            bool depthSuccess =
                SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &renderSupport));
            renderable =
                depthSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0);
            if (renderable)
            {
                EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.dsvFormat);
            }
        }
        else
        {
            renderFormat = formatInfo.rtvFormat;
            bool rtSuccess =
                SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &renderSupport));
            renderable = rtSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0);
            if (renderable)
            {
                EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.rtvFormat);
            }
        }
        EXPECT_EQ(renderable, textureInfo.renderable);
        if (!textureInfo.sampleCounts.empty())
        {
            EXPECT_TRUE(renderable);
        }

        // Multisample counts
        if (renderable)
        {
            if ((renderSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)
            {
                EXPECT_TRUE(!textureInfo.sampleCounts.empty());
                for (unsigned int sampleCount = 1;
                     sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2)
                {
                    UINT qualityCount  = 0;
                    bool sampleSuccess = SUCCEEDED(device->CheckMultisampleQualityLevels(
                        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