1 //
2 // Copyright (c) 2012-2014 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 // RenderStateCache.h: Defines rx::RenderStateCache, a cache of Direct3D render
8 // state objects.
9 
10 #ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
11 #define LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
12 
13 #include "common/angleutils.h"
14 #include "libANGLE/Error.h"
15 #include "libANGLE/SizedMRUCache.h"
16 #include "libANGLE/angletypes.h"
17 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
18 
19 #include <unordered_map>
20 
21 namespace gl
22 {
23 class Framebuffer;
24 }
25 
26 namespace std
27 {
28 template <>
29 struct hash<rx::d3d11::BlendStateKey>
30 {
31     size_t operator()(const rx::d3d11::BlendStateKey &key) const
32     {
33         return angle::ComputeGenericHash(key);
34     }
35 };
36 
37 template <>
38 struct hash<rx::d3d11::RasterizerStateKey>
39 {
40     size_t operator()(const rx::d3d11::RasterizerStateKey &key) const
41     {
42         return angle::ComputeGenericHash(key);
43     }
44 };
45 
46 template <>
47 struct hash<gl::DepthStencilState>
48 {
49     size_t operator()(const gl::DepthStencilState &key) const
50     {
51         return angle::ComputeGenericHash(key);
52     }
53 };
54 
55 template <>
56 struct hash<gl::SamplerState>
57 {
58     size_t operator()(const gl::SamplerState &key) const { return angle::ComputeGenericHash(key); }
59 };
60 }  // namespace std
61 
62 namespace rx
63 {
64 class Renderer11;
65 
66 class RenderStateCache : angle::NonCopyable
67 {
68   public:
69     RenderStateCache();
70     virtual ~RenderStateCache();
71 
72     void clear();
73 
74     static d3d11::BlendStateKey GetBlendStateKey(const gl::Context *context,
75                                                  const gl::Framebuffer *framebuffer,
76                                                  const gl::BlendState &blendState);
77     gl::Error getBlendState(Renderer11 *renderer,
78                             const d3d11::BlendStateKey &key,
79                             const d3d11::BlendState **outBlendState);
80     gl::Error getRasterizerState(Renderer11 *renderer,
81                                  const gl::RasterizerState &rasterState,
82                                  bool scissorEnabled,
83                                  ID3D11RasterizerState **outRasterizerState);
84     gl::Error getDepthStencilState(Renderer11 *renderer,
85                                    const gl::DepthStencilState &dsState,
86                                    const d3d11::DepthStencilState **outDSState);
87     gl::Error getSamplerState(Renderer11 *renderer,
88                               const gl::SamplerState &samplerState,
89                               ID3D11SamplerState **outSamplerState);
90 
91   private:
92     // MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState,
93     // ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum
94     // number of unique states of each type an application can create is 4096
95     // TODO(ShahmeerEsmail): Revisit the cache sizes to make sure they are appropriate for most
96     // scenarios.
97     static constexpr unsigned int kMaxStates = 4096;
98 
99     // The cache tries to clean up this many states at once.
100     static constexpr unsigned int kGCLimit = 128;
101 
102     // Blend state cache
103     using BlendStateMap = angle::base::HashingMRUCache<d3d11::BlendStateKey, d3d11::BlendState>;
104     BlendStateMap mBlendStateCache;
105 
106     // Rasterizer state cache
107     using RasterizerStateMap =
108         angle::base::HashingMRUCache<d3d11::RasterizerStateKey, d3d11::RasterizerState>;
109     RasterizerStateMap mRasterizerStateCache;
110 
111     // Depth stencil state cache
112     using DepthStencilStateMap =
113         angle::base::HashingMRUCache<gl::DepthStencilState, d3d11::DepthStencilState>;
114     DepthStencilStateMap mDepthStencilStateCache;
115 
116     // Sample state cache
117     using SamplerStateMap = angle::base::HashingMRUCache<gl::SamplerState, d3d11::SamplerState>;
118     SamplerStateMap mSamplerStateCache;
119 };
120 
121 }  // namespace rx
122 
123 #endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
124