1 //
2 // Copyright (c) 2012 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 
7 // InputLayoutCache.h: Defines InputLayoutCache, a class that builds and caches
8 // D3D11 input layouts.
9 
10 #ifndef LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
11 #define LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
12 
13 #include <GLES2/gl2.h>
14 
15 #include <cstddef>
16 
17 #include <array>
18 #include <map>
19 
20 #include "common/angleutils.h"
21 #include "libANGLE/Constants.h"
22 #include "libANGLE/Error.h"
23 #include "libANGLE/SizedMRUCache.h"
24 #include "libANGLE/formatutils.h"
25 #include "libANGLE/renderer/d3d/RendererD3D.h"
26 #include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
27 
28 namespace rx
29 {
30 class DrawCallVertexParams;
31 struct PackedAttributeLayout
32 {
33     PackedAttributeLayout();
34     PackedAttributeLayout(const PackedAttributeLayout &other);
35 
36     void addAttributeData(GLenum glType,
37                           UINT semanticIndex,
38                           gl::VertexFormatType vertexFormatType,
39                           unsigned int divisor);
40 
41     bool operator==(const PackedAttributeLayout &other) const;
42 
43     enum Flags
44     {
45         FLAG_USES_INSTANCED_SPRITES     = 0x1,
46         FLAG_INSTANCED_SPRITES_ACTIVE   = 0x2,
47         FLAG_INSTANCED_RENDERING_ACTIVE = 0x4,
48     };
49 
50     uint32_t numAttributes;
51     uint32_t flags;
52     std::array<uint32_t, gl::MAX_VERTEX_ATTRIBS> attributeData;
53 };
54 }  // namespace rx
55 
56 namespace std
57 {
58 template <>
59 struct hash<rx::PackedAttributeLayout>
60 {
61     size_t operator()(const rx::PackedAttributeLayout &value) const
62     {
63         return angle::ComputeGenericHash(value);
64     }
65 };
66 }  // namespace std
67 
68 namespace gl
69 {
70 class Program;
71 }  // namespace gl
72 
73 namespace rx
74 {
75 struct TranslatedAttribute;
76 struct TranslatedIndexData;
77 struct SourceIndexData;
78 class ProgramD3D;
79 class Renderer11;
80 
81 class InputLayoutCache : angle::NonCopyable
82 {
83   public:
84     InputLayoutCache();
85     ~InputLayoutCache();
86 
87     void clear();
88 
89     gl::Error applyVertexBuffers(const gl::Context *context,
90                                  const std::vector<const TranslatedAttribute *> &currentAttributes,
91                                  GLenum mode,
92                                  GLint start,
93                                  bool isIndexedRendering);
94 
95     gl::Error updateVertexOffsetsForPointSpritesEmulation(
96         Renderer11 *renderer,
97         const std::vector<const TranslatedAttribute *> &currentAttributes,
98         GLint startVertex,
99         GLsizei emulatedInstanceId);
100 
101     // Useful for testing
102     void setCacheSize(size_t newCacheSize);
103 
104     gl::Error updateInputLayout(Renderer11 *renderer,
105                                 const gl::State &state,
106                                 const std::vector<const TranslatedAttribute *> &currentAttributes,
107                                 GLenum mode,
108                                 const AttribIndexArray &sortedSemanticIndices,
109                                 const DrawCallVertexParams &vertexParams);
110 
111   private:
112     gl::Error createInputLayout(Renderer11 *renderer,
113                                 const AttribIndexArray &sortedSemanticIndices,
114                                 const std::vector<const TranslatedAttribute *> &currentAttributes,
115                                 GLenum mode,
116                                 gl::Program *program,
117                                 const DrawCallVertexParams &vertexParams,
118                                 d3d11::InputLayout *inputLayoutOut);
119 
120     // Starting cache size.
121     static constexpr size_t kDefaultCacheSize = 1024;
122 
123     // The cache tries to clean up this many states at once.
124     static constexpr size_t kGCLimit = 128;
125 
126     using LayoutCache = angle::base::HashingMRUCache<PackedAttributeLayout, d3d11::InputLayout>;
127     LayoutCache mLayoutCache;
128 
129     d3d11::Buffer mPointSpriteVertexBuffer;
130     d3d11::Buffer mPointSpriteIndexBuffer;
131 };
132 
133 }  // namespace rx
134 
135 #endif // LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
136