]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_program_state.h
Initial vogl checkin
[vogl] / src / voglcommon / vogl_program_state.h
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 // File: vogl_program_state.h
27 #ifndef VOGL_PROGRAM_STATE_H
28 #define VOGL_PROGRAM_STATE_H
29
30 #include "vogl_common.h"
31 #include "vogl_dynamic_string.h"
32 #include "vogl_json.h"
33 #include "vogl_map.h"
34 #include "vogl_unique_ptr.h"
35
36 #include "vogl_general_context_state.h"
37 #include "vogl_blob_manager.h"
38 #include "vogl_shader_state.h"
39
40 struct vogl_program_attrib_state
41 {
42     GLint m_size;
43     GLenum m_type;
44     dynamic_string m_name;
45     GLint m_bound_location;
46
47     void clear()
48     {
49         m_size = 0;
50         m_type = GL_NONE;
51         m_name.clear();
52         m_bound_location = 0;
53     }
54
55     inline bool operator==(const vogl_program_attrib_state &rhs) const
56     {
57         return (m_size == rhs.m_size) && (m_type == rhs.m_type) && (!m_name.compare(rhs.m_name, true)) && (m_bound_location == rhs.m_bound_location);
58     }
59 };
60
61 typedef vogl::vector<vogl_program_attrib_state> vogl_attrib_state_vec;
62
63 struct vogl_program_uniform_state
64 {
65     GLint m_size;
66     GLenum m_type;
67     dynamic_string m_name;
68     GLint m_base_location;
69     growable_array<uint8, 16> m_data;
70
71     void clear()
72     {
73         m_size = 0;
74         m_type = GL_NONE;
75         m_name.clear();
76         m_base_location = 0;
77         m_data.clear();
78     }
79
80     inline bool operator==(const vogl_program_uniform_state &rhs) const
81     {
82         return (m_size == rhs.m_size) && (m_type == rhs.m_type) && (!m_name.compare(rhs.m_name, true)) && (m_base_location == rhs.m_base_location) && (m_data == rhs.m_data);
83     }
84 };
85
86 typedef vogl::vector<vogl_program_uniform_state> vogl_uniform_state_vec;
87
88 struct vogl_program_uniform_block_state
89 {
90     GLuint m_uniform_block_index;
91     dynamic_string m_name;
92     GLint m_uniform_block_binding_point;
93     GLint m_uniform_block_data_size;
94     GLint m_uniform_block_active_uniforms;
95
96     void clear()
97     {
98         m_uniform_block_index = 0;
99         m_name.clear();
100         m_uniform_block_binding_point = 0;
101         m_uniform_block_data_size = 0;
102         m_uniform_block_active_uniforms = 0;
103     }
104
105     inline bool operator==(const vogl_program_uniform_block_state &rhs) const
106     {
107 #define CMP(x)      \
108     if (x != rhs.x) \
109         return false;
110         CMP(m_uniform_block_index)
111         CMP(m_name)
112         CMP(m_uniform_block_binding_point)
113         CMP(m_uniform_block_data_size)
114         CMP(m_uniform_block_active_uniforms)
115 #undef CMP
116         return true;
117     }
118 };
119
120 typedef vogl::vector<vogl_program_uniform_block_state> vogl_uniform_block_state_vec;
121
122 struct vogl_program_output_state
123 {
124     dynamic_string m_name;
125     GLint m_location;
126     GLint m_location_index;
127     GLenum m_type;
128     GLint m_array_size;
129     bool m_is_per_patch;
130     //GLint m_location_component; // TODO
131
132     void clear()
133     {
134         utils::zero_object(*this);
135     }
136
137     inline bool operator==(const vogl_program_output_state &rhs) const
138     {
139 #define CMP(x)      \
140     if (x != rhs.x) \
141         return false;
142         CMP(m_name)
143         CMP(m_location);
144         CMP(m_location_index);
145         CMP(m_type);
146         CMP(m_array_size);
147         CMP(m_is_per_patch);
148 //CMP(m_location_component);
149 #undef CMP
150         return true;
151     }
152 };
153
154 typedef vogl::vector<vogl_program_output_state> vogl_program_output_state_vec;
155
156 struct vogl_program_transform_feedback_varying
157 {
158     GLint m_index;
159     dynamic_string m_name;
160     GLsizei m_size;
161     GLenum m_type;
162
163     void clear()
164     {
165         m_index = 0;
166         m_name.clear();
167         m_size = 0;
168         m_type = GL_NONE;
169     }
170
171     inline bool operator==(const vogl_program_transform_feedback_varying &rhs) const
172     {
173 #define CMP(x)      \
174     if (x != rhs.x) \
175         return false;
176         CMP(m_index)
177         CMP(m_name);
178         CMP(m_size);
179         CMP(m_type);
180 #undef CMP
181         return true;
182     }
183 };
184
185 typedef vogl::vector<vogl_program_transform_feedback_varying> vogl_program_transform_feedback_varying_vec;
186
187 class vogl_program_state : public vogl_gl_object_state
188 {
189 public:
190     vogl_program_state();
191     vogl_program_state(const vogl_program_state &other);
192     virtual ~vogl_program_state();
193
194     vogl_program_state &operator=(const vogl_program_state &rhs);
195
196     virtual vogl_gl_object_state_type get_type() const
197     {
198         return cGLSTProgram;
199     }
200     virtual vogl_namespace_t get_handle_namespace() const
201     {
202         return VOGL_NAMESPACE_PROGRAMS;
203     }
204
205     virtual bool snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target);
206
207     virtual bool restore(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 &handle) const;
208
209     virtual bool remap_handles(vogl_handle_remapper &remapper);
210
211     virtual void clear();
212
213     virtual bool is_valid() const
214     {
215         return m_is_valid;
216     }
217
218     virtual bool serialize(json_node &node, vogl_blob_manager &blob_manager) const;
219     virtual bool deserialize(const json_node &node, const vogl_blob_manager &blob_manager);
220
221     virtual GLuint64 get_snapshot_handle() const
222     {
223         return m_snapshot_handle;
224     }
225
226     virtual bool compare_restorable_state(const vogl_gl_object_state &rhs_obj) const;
227
228     virtual bool get_marked_for_deletion() const
229     {
230         return m_marked_for_deletion;
231     }
232
233     const dynamic_string &get_info_log() const
234     {
235         return m_info_log;
236     }
237
238     bool link_snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint handle, const void *pBinary = NULL, uint binary_size = 0, GLenum binary_format = GL_NONE);
239
240     void set_link_time_snapshot(vogl_unique_ptr<vogl_program_state> &pSnapshot);
241
242     const vogl_unique_ptr<vogl_program_state> &get_link_time_snapshot() const
243     {
244         return m_pLink_time_snapshot;
245     }
246     vogl_unique_ptr<vogl_program_state> &get_link_time_snapshot()
247     {
248         return m_pLink_time_snapshot;
249     }
250
251     bool has_link_time_snapshot() const
252     {
253         return m_pLink_time_snapshot.get() != NULL;
254     }
255
256     bool is_link_snapshot() const
257     {
258         return m_link_snapshot;
259     }
260
261     bool get_link_status() const
262     {
263         return m_link_status;
264     }
265     bool get_verify_status() const
266     {
267         return m_verify_status;
268     }
269
270     uint get_num_active_attribs() const
271     {
272         return m_num_active_attribs;
273     }
274     uint get_num_active_uniforms() const
275     {
276         return m_num_active_uniforms;
277     }
278     uint get_num_active_uniform_blocks() const
279     {
280         return m_num_active_uniform_blocks;
281     }
282
283     typedef vogl::vector<GLuint> attached_shader_vec;
284     const attached_shader_vec &get_attached_shaders() const
285     {
286         return m_attached_shaders;
287     }
288
289     const vogl_attrib_state_vec &get_attrib_state_vec() const
290     {
291         return m_attribs;
292     }
293
294     const vogl_uniform_state_vec &get_uniform_state_vec() const
295     {
296         return m_uniforms;
297     }
298
299     const vogl_uniform_block_state_vec &get_uniform_block_state_vec()
300     {
301         return m_uniform_blocks;
302     }
303
304     const uint8_vec &get_program_binary() const
305     {
306         return m_program_binary;
307     }
308     GLenum get_program_binary_format() const
309     {
310         return m_program_binary_format;
311     }
312
313     uint get_program_binary_size() const
314     {
315         return m_program_binary.size();
316     }
317
318     const vogl_shader_state_vec &get_shaders() const
319     {
320         return m_shaders;
321     }
322
323     vogl_shader_state_vec &get_shaders()
324     {
325         return m_shaders;
326     }
327
328     const vogl_program_output_state_vec &get_outputs() const
329     {
330         return m_outputs;
331     }
332
333     // The LATEST transform feedback mode.
334     GLenum get_transform_feedback_mode() const
335     {
336         return m_transform_feedback_mode;
337     }
338
339     // These are the varyings as of the last link, NOT the very latest varyings.
340     uint get_transform_feedback_num_varyings() const
341     {
342         return m_transform_feedback_num_varyings;
343     }
344
345     // These are the varyings as of the last link, NOT the very latest varyings.
346     const vogl_program_transform_feedback_varying_vec &get_varyings() const
347     {
348         return m_varyings;
349     }
350
351     bool compare_full_state(const vogl_program_state &rhs) const;
352
353 private:
354     GLuint m_snapshot_handle;
355
356     uint8_vec m_program_binary;
357     GLenum m_program_binary_format;
358
359     attached_shader_vec m_attached_shaders;
360
361     dynamic_string m_info_log;
362
363     uint m_num_active_attribs;
364     uint m_num_active_uniforms;
365     uint m_num_active_uniform_blocks;
366
367     vogl_attrib_state_vec m_attribs;
368     vogl_uniform_state_vec m_uniforms;
369     vogl_uniform_block_state_vec m_uniform_blocks;
370
371     vogl_shader_state_vec m_shaders;
372
373     vogl_program_output_state_vec m_outputs;
374
375     vogl_unique_ptr<vogl_program_state> m_pLink_time_snapshot;
376
377     GLenum m_transform_feedback_mode;
378     uint m_transform_feedback_num_varyings;
379     vogl_program_transform_feedback_varying_vec m_varyings;
380
381     bool m_marked_for_deletion;
382     bool m_link_status;
383     bool m_verify_status;
384     bool m_link_snapshot;
385
386     bool m_is_valid;
387
388     bool snapshot_uniforms(const vogl_context_info &context_info, vogl_handle_remapper &remapper);
389     bool snapshot_uniform_blocks(const vogl_context_info &context_info, vogl_handle_remapper &remapper);
390     bool snapshot_active_attribs(const vogl_context_info &context_info, vogl_handle_remapper &remapper);
391     bool snapshot_attached_shaders(const vogl_context_info &context_info, vogl_handle_remapper &remapper, bool linked_using_binary);
392     bool snapshot_shader_objects(const vogl_context_info &context_info, vogl_handle_remapper &remapper);
393     bool snapshot_info_log(const vogl_context_info &context_info, vogl_handle_remapper &remapper);
394     bool snapshot_program_binary(const vogl_context_info &context_info, vogl_handle_remapper &remapper);
395     bool snapshot_basic_info(const vogl_context_info &context_info, vogl_handle_remapper &remapper);
396     bool snapshot_outputs(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint program);
397     bool snapshot_transform_feedback(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint program);
398     bool restore_uniforms(uint32 handle32, const vogl_context_info &context_info, vogl_handle_remapper &remapper, bool &any_restore_warnings, bool &any_gl_errors) const;
399     bool restore_uniform_blocks(uint32 handle32, const vogl_context_info &context_info, vogl_handle_remapper &remapper, bool &any_restore_warnings, bool &any_gl_errors) const;
400     bool restore_active_attribs(uint32 handle32, const vogl_context_info &context_info, vogl_handle_remapper &remapper, bool &any_restore_warnings, bool &any_gl_errors) const;
401     bool restore_outputs(uint32 handle32, const vogl_context_info &context_info, vogl_handle_remapper &remapper, bool &any_restore_warnings, bool &any_gl_errors) const;
402     bool restore_transform_feedback(uint32 handle32, const vogl_context_info &context_info, vogl_handle_remapper &remapper, bool &any_restore_warnings, bool &any_gl_errors) const;
403     bool restore_link_snapshot(uint32 handle32, const vogl_context_info &context_info, vogl_handle_remapper &remapper, bool &any_restore_warnings, bool &any_gl_errors, bool &link_succeeded) const;
404     bool link_program(uint32 handle32, const vogl_context_info &context_info, vogl_handle_remapper &remapper, bool &any_restore_warnings, bool &any_gl_errors, bool &link_succeeded) const;
405 };
406
407 typedef vogl::map<GLuint, vogl_program_state> vogl_program_state_map;
408
409 class vogl_linked_program_state
410 {
411 public:
412     vogl_linked_program_state();
413     vogl_linked_program_state(const vogl_linked_program_state &other);
414     ~vogl_linked_program_state();
415
416     vogl_linked_program_state &operator=(const vogl_linked_program_state &rhs);
417
418     void clear();
419
420     bool add_snapshot(GLuint handle, const vogl_program_state &prog);
421     bool add_snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint handle, GLenum binary_format = GL_NONE, const void *pBinary = NULL, uint binary_size = 0);
422     bool remove_snapshot(GLuint handle);
423
424     const vogl_program_state *find_snapshot(GLuint handle) const;
425     vogl_program_state *find_snapshot(GLuint handle);
426
427     bool serialize(json_node &node, vogl_blob_manager &blob_manager) const;
428     bool deserialize(const json_node &node, const vogl_blob_manager &blob_manager);
429
430     bool remap_handles(vogl_handle_remapper &remapper);
431
432     const vogl_program_state_map &get_linked_program_map() const
433     {
434         return m_linked_programs;
435     }
436
437     vogl_program_state_map &get_linked_program_map()
438     {
439         return m_linked_programs;
440     }
441
442 private:
443     vogl_program_state_map m_linked_programs;
444 };
445
446 #endif // VOGL_PROGRAM_STATE_H