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