xref: /aosp_15_r20/external/angle/src/tests/gl_tests/D3D11InputLayoutCacheTest.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 // D3D11InputLayoutCacheTest:
7 //   Stress to to reproduce a bug where we weren't flushing the case correctly.
8 //
9 
10 #include <sstream>
11 
12 #include "libANGLE/Context.h"
13 #include "libANGLE/Display.h"
14 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
15 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
16 #include "test_utils/ANGLETest.h"
17 #include "test_utils/angle_test_instantiate.h"
18 #include "util/EGLWindow.h"
19 
20 using namespace angle;
21 
22 namespace
23 {
24 
25 class D3D11InputLayoutCacheTest : public ANGLETest<>
26 {
27   protected:
D3D11InputLayoutCacheTest()28     D3D11InputLayoutCacheTest()
29     {
30         setWindowWidth(64);
31         setWindowHeight(64);
32         setConfigRedBits(8);
33         setConfigAlphaBits(8);
34     }
35 
makeProgramWithAttribCount(unsigned int attribCount)36     GLuint makeProgramWithAttribCount(unsigned int attribCount)
37     {
38         std::stringstream strstr;
39 
40         strstr << "attribute vec2 position;" << std::endl;
41         for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
42         {
43             strstr << "attribute float a" << attribIndex << ";" << std::endl;
44         }
45         strstr << "varying float v;" << std::endl
46                << "void main() {" << std::endl
47                << "    v = 0.0;" << std::endl;
48         for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
49         {
50             strstr << "    v += a" << attribIndex << ";" << std::endl;
51         }
52         strstr << "    gl_Position = vec4(position, 0.0, 1.0);" << std::endl << "}" << std::endl;
53 
54         constexpr char kFS[] =
55             "varying highp float v;\n"
56             "void main() {"
57             "   gl_FragColor = vec4(v / 255.0, 0.0, 0.0, 1.0);\n"
58             "}\n";
59 
60         return CompileProgram(strstr.str().c_str(), kFS);
61     }
62 };
63 
64 // Stress the cache by setting a small cache size and drawing with a bunch of shaders
65 // with different input signatures.
TEST_P(D3D11InputLayoutCacheTest,StressTest)66 TEST_P(D3D11InputLayoutCacheTest, StressTest)
67 {
68     // Hack the ANGLE!
69     egl::Display *display   = static_cast<egl::Display *>(getEGLWindow()->getDisplay());
70     gl::ContextID contextID = {
71         static_cast<GLuint>(reinterpret_cast<uintptr_t>(getEGLWindow()->getContext()))};
72     gl::Context *context                   = display->getContext(contextID);
73     rx::Context11 *context11               = rx::GetImplAs<rx::Context11>(context);
74     rx::Renderer11 *renderer11             = context11->getRenderer();
75     rx::InputLayoutCache *inputLayoutCache = renderer11->getStateManager()->getInputLayoutCache();
76 
77     // Clamp the cache size to something tiny
78     inputLayoutCache->setCacheSize(4);
79 
80     GLint maxAttribs = 0;
81     context->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs);
82 
83     // Reserve one attrib for position
84     unsigned int maxInputs = static_cast<unsigned int>(maxAttribs) - 2;
85 
86     std::vector<GLuint> programs;
87     for (unsigned int attribCount = 0; attribCount <= maxInputs; ++attribCount)
88     {
89         GLuint program = makeProgramWithAttribCount(attribCount);
90         ASSERT_NE(0u, program);
91         programs.push_back(program);
92     }
93 
94     // Iteratively do a simple drop operation, trying every attribute count from 0..MAX_ATTRIBS.
95     // This should thrash the cache.
96     for (unsigned int iterationCount = 0; iterationCount < 10; ++iterationCount)
97     {
98         ASSERT_GL_NO_ERROR();
99 
100         for (unsigned int attribCount = 0; attribCount <= maxInputs; ++attribCount)
101         {
102             GLuint program = programs[attribCount];
103             glUseProgram(program);
104 
105             for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
106             {
107                 std::stringstream attribNameStr;
108                 attribNameStr << "a" << attribIndex;
109                 std::string attribName = attribNameStr.str();
110 
111                 GLint location = glGetAttribLocation(program, attribName.c_str());
112                 ASSERT_NE(-1, location);
113                 glVertexAttrib1f(location, 1.0f);
114                 glDisableVertexAttribArray(location);
115             }
116 
117             drawQuad(program, "position", 0.5f);
118             EXPECT_PIXEL_EQ(0, 0, attribCount, 0, 0, 255u);
119         }
120     }
121 
122     for (GLuint program : programs)
123     {
124         glDeleteProgram(program);
125     }
126 }
127 
128 ANGLE_INSTANTIATE_TEST(D3D11InputLayoutCacheTest, ES2_D3D11(), ES3_D3D11(), ES31_D3D11());
129 
130 }  // anonymous namespace
131