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