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