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