blob: 93d7267916b580a19f67fcf9e98d0810f4cedb87 [file] [log] [blame]
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +00001//
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
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +00007// ShaderCache: Defines rx::ShaderCache, a cache of Direct3D shader objects
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +00008// keyed by their byte code.
9
daniel@transgaming.come4733d72012-10-31 18:07:01 +000010#ifndef LIBGLESV2_RENDERER_SHADER_CACHE_H_
11#define LIBGLESV2_RENDERER_SHADER_CACHE_H_
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000012
13#include <d3d9.h>
daniel@transgaming.comdb2115d2012-08-27 16:25:33 +000014
15#ifdef _MSC_VER
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000016#include <hash_map>
daniel@transgaming.comdb2115d2012-08-27 16:25:33 +000017#else
18#include <unordered_map>
19#endif
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000020
daniel@transgaming.come4733d72012-10-31 18:07:01 +000021#include "common/debug.h"
22
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +000023namespace rx
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000024{
25template <typename ShaderObject>
26class ShaderCache
27{
28 public:
29 ShaderCache() : mDevice(NULL)
30 {
31 }
32
33 ~ShaderCache()
34 {
35 // Call clear while the device is still valid.
36 ASSERT(mMap.empty());
37 }
38
39 void initialize(IDirect3DDevice9* device)
40 {
41 mDevice = device;
42 }
43
44 ShaderObject *create(const DWORD *function, size_t length)
45 {
46 std::string key(reinterpret_cast<const char*>(function), length);
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000047 typename Map::iterator it = mMap.find(key);
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000048 if (it != mMap.end())
49 {
50 it->second->AddRef();
51 return it->second;
52 }
daniel@transgaming.come4733d72012-10-31 18:07:01 +000053
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000054 ShaderObject *shader;
55 HRESULT result = createShader(function, &shader);
56 if (FAILED(result))
57 {
58 return NULL;
59 }
60
61 // Random eviction policy.
62 if (mMap.size() >= kMaxMapSize)
63 {
64 mMap.begin()->second->Release();
65 mMap.erase(mMap.begin());
66 }
67
68 shader->AddRef();
69 mMap[key] = shader;
70
71 return shader;
72 }
73
74 void clear()
75 {
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000076 for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it)
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000077 {
78 it->second->Release();
79 }
80
81 mMap.clear();
82 }
83
84 private:
85 DISALLOW_COPY_AND_ASSIGN(ShaderCache);
86
87 const static size_t kMaxMapSize = 100;
88
89 HRESULT createShader(const DWORD *function, IDirect3DVertexShader9 **shader)
90 {
91 return mDevice->CreateVertexShader(function, shader);
92 }
93
94 HRESULT createShader(const DWORD *function, IDirect3DPixelShader9 **shader)
95 {
96 return mDevice->CreatePixelShader(function, shader);
97 }
98
daniel@transgaming.comdb2115d2012-08-27 16:25:33 +000099#ifndef HASH_MAP
100# ifdef _MSC_VER
101# define HASH_MAP stdext::hash_map
102# else
103# define HASH_MAP std::unordered_map
104# endif
105#endif
106
107 typedef HASH_MAP<std::string, ShaderObject*> Map;
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +0000108 Map mMap;
109
110 IDirect3DDevice9 *mDevice;
111};
112
113typedef ShaderCache<IDirect3DVertexShader9> VertexShaderCache;
114typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
115
116}
117
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000118#endif // LIBGLESV2_RENDERER_SHADER_CACHE_H_