Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_SHADERDEFINES
19 : #define INCLUDED_SHADERDEFINES
20 :
21 : #include "ps/CStr.h"
22 : #include "ps/CStrIntern.h"
23 : #include "renderer/backend/IDeviceCommandContext.h"
24 : #include "renderer/backend/IShaderProgram.h"
25 :
26 : #include <map>
27 : #include <unordered_map>
28 : #include <vector>
29 :
30 : class CVector4D;
31 :
32 : /**
33 : * Represents a mapping of name strings to value, for use with
34 : * CShaderDefines (values are strings) and CShaderUniforms (values are vec4s).
35 : *
36 : * Stored as interned vectors of name-value pairs, to support high performance
37 : * comparison operators.
38 : *
39 : * Not thread-safe - must only be used from the main thread.
40 : */
41 : template<typename value_t>
42 : class CShaderParams
43 : {
44 : public:
45 : /**
46 : * Create an empty map of defines.
47 : */
48 : CShaderParams();
49 :
50 : /**
51 : * Add a name and associated value to the map of parameters.
52 : * If the name is already defined, its value will be replaced.
53 : */
54 : void Set(CStrIntern name, const value_t& value);
55 :
56 : /**
57 : * Add all the names and values from another set of parameters.
58 : * If any name is already defined in this object, its value will be replaced.
59 : */
60 : void SetMany(const CShaderParams& params);
61 :
62 : /**
63 : * Return a copy of the current name/value mapping.
64 : */
65 : std::map<CStrIntern, value_t> GetMap() const;
66 :
67 : /**
68 : * Return a hash of the current mapping.
69 : */
70 : size_t GetHash() const;
71 :
72 : /**
73 : * Compare with some arbitrary total order.
74 : * The order may be different each time the application is run
75 : * (it is based on interned memory addresses).
76 : */
77 4 : bool operator<(const CShaderParams& b) const
78 : {
79 4 : return m_Items < b.m_Items;
80 : }
81 :
82 : /**
83 : * Fast equality comparison.
84 : */
85 11 : bool operator==(const CShaderParams& b) const
86 : {
87 11 : return m_Items == b.m_Items;
88 : }
89 :
90 : /**
91 : * Fast inequality comparison.
92 : */
93 0 : bool operator!=(const CShaderParams& b) const
94 : {
95 0 : return m_Items != b.m_Items;
96 : }
97 :
98 194 : struct SItems
99 : {
100 : // Name/value pair
101 : using Item = std::pair<CStrIntern, value_t>;
102 :
103 : // Sorted by name; no duplicated names
104 : std::vector<Item> items;
105 :
106 : size_t hash;
107 :
108 : void RecalcHash();
109 :
110 : static bool NameLess(const Item& a, const Item& b);
111 : };
112 :
113 : struct SItemsHash
114 : {
115 59 : std::size_t operator()(const SItems& items) const
116 : {
117 59 : return items.hash;
118 : }
119 : };
120 :
121 : protected:
122 : SItems* m_Items; // interned value
123 :
124 : private:
125 : using InternedItems_t = std::unordered_map<SItems, std::shared_ptr<SItems>, SItemsHash>;
126 : static InternedItems_t s_InternedItems;
127 :
128 : /**
129 : * Returns a pointer to an SItems equal to @p items.
130 : * The pointer will be valid forever, and the same pointer will be returned
131 : * for any subsequent requests for an equal items list.
132 : */
133 : static SItems* GetInterned(const SItems& items);
134 :
135 : CShaderParams(SItems* items);
136 : static CShaderParams CreateEmpty();
137 : static CShaderParams s_Empty;
138 : };
139 :
140 : /**
141 : * Represents a mapping of name strings to value strings, for use with
142 : * \#if and \#ifdef and similar conditionals in shaders.
143 : *
144 : * Not thread-safe - must only be used from the main thread.
145 : */
146 30 : class CShaderDefines : public CShaderParams<CStrIntern>
147 : {
148 : public:
149 : /**
150 : * Add a name and associated value to the map of defines.
151 : * If the name is already defined, its value will be replaced.
152 : */
153 : void Add(CStrIntern name, CStrIntern value);
154 :
155 : /**
156 : * Return the value for the given name as an integer, or 0 if not defined.
157 : */
158 : int GetInt(const char* name) const;
159 : };
160 :
161 : /**
162 : * Represents a mapping of name strings to value CVector4Ds, for use with
163 : * uniforms in shaders.
164 : *
165 : * Not thread-safe - must only be used from the main thread.
166 : */
167 2 : class CShaderUniforms : public CShaderParams<CVector4D>
168 : {
169 : public:
170 : /**
171 : * Add a name and associated value to the map of uniforms.
172 : * If the name is already defined, its value will be replaced.
173 : */
174 : void Add(const char* name, const CVector4D& value);
175 :
176 : /**
177 : * Return the value for the given name, or (0,0,0,0) if not defined.
178 : */
179 : CVector4D GetVector(const char* name) const;
180 :
181 : /**
182 : * Bind the collection of uniforms onto the given shader.
183 : */
184 : void BindUniforms(
185 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
186 : Renderer::Backend::IShaderProgram* shader) const;
187 : };
188 :
189 : // Add here the types of queries we can make in the renderer
190 : enum RENDER_QUERIES
191 : {
192 : RQUERY_TIME,
193 : RQUERY_WATER_TEX,
194 : RQUERY_SKY_CUBE
195 : };
196 :
197 : /**
198 : * Uniform values that need to be evaluated in the renderer.
199 : *
200 : * Not thread-safe - must only be used from the main thread.
201 : */
202 0 : class CShaderRenderQueries
203 : {
204 : public:
205 : using RenderQuery = std::pair<int, CStrIntern>;
206 :
207 : void Add(const char* name);
208 0 : size_t GetSize() const { return m_Items.size(); }
209 0 : RenderQuery GetItem(size_t i) const { return m_Items[i]; }
210 : private:
211 : std::vector<RenderQuery> m_Items;
212 : };
213 :
214 : #endif // INCLUDED_SHADERDEFINES
|