blob: 118d10600aa30b92724d4f705eb55a5abb424ead [file] [log] [blame]
Jamie Madill531d5f42015-07-06 08:26:45 -04001//
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"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040013#include "libANGLE/renderer/d3d/d3d11/Context11.h"
Jamie Madill531d5f42015-07-06 08:26:45 -040014#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
15#include "test_utils/ANGLETest.h"
16#include "test_utils/angle_test_instantiate.h"
17
18using namespace angle;
19
20namespace
21{
22
23class D3D11InputLayoutCacheTest : public ANGLETest
24{
25 protected:
Jamie Madill2810a202015-07-07 14:23:58 -040026 D3D11InputLayoutCacheTest()
27 {
28 setWindowWidth(64);
29 setWindowHeight(64);
30 setConfigRedBits(8);
Cooper Partind7561452015-09-10 10:23:29 -070031 setConfigAlphaBits(8);
Jamie Madill2810a202015-07-07 14:23:58 -040032 }
33
Jamie Madill531d5f42015-07-06 08:26:45 -040034 GLuint makeProgramWithAttribCount(unsigned int attribCount)
35 {
36 std::stringstream strstr;
37
38 strstr << "attribute vec2 position;" << std::endl;
39 for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
40 {
41 strstr << "attribute float a" << attribIndex << ";" << std::endl;
42 }
43 strstr << "varying float v;" << std::endl
44 << "void main() {" << std::endl
45 << " v = 0.0;" << std::endl;
46 for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
47 {
48 strstr << " v += a" << attribIndex << ";" << std::endl;
49 }
50 strstr << " gl_Position = vec4(position, 0.0, 1.0);" << std::endl
51 << "}" << std::endl;
52
53 const std::string basicFragmentShader =
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(), basicFragmentShader);
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.
65TEST_P(D3D11InputLayoutCacheTest, StressTest)
66{
67 // Hack the ANGLE!
68 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
Jamie Madill53ea9cc2016-05-17 10:12:52 -040069 rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
70 rx::Renderer11 *renderer11 = context11->getRenderer();
Jamie Madill401345e2017-08-21 10:52:40 -040071 rx::InputLayoutCache *inputLayoutCache = renderer11->getStateManager()->getInputLayoutCache();
Jamie Madill531d5f42015-07-06 08:26:45 -040072
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
124ANGLE_INSTANTIATE_TEST(D3D11InputLayoutCacheTest, ES2_D3D11());
125
126} // anonymous namespace