]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_gl_state_snapshot.h
Initial vogl checkin
[vogl] / src / voglcommon / vogl_gl_state_snapshot.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_gl_state_snapshot.h
27 #ifndef VOGL_GL_STATE_SNAPSHOT_H
28 #define VOGL_GL_STATE_SNAPSHOT_H
29
30 #include "vogl_core.h"
31 #include "vogl_sparse_vector.h"
32 #include "vogl_md5.h"
33
34 #include "vogl_common.h"
35 #include "vogl_general_context_state.h"
36 #include "vogl_texture_state.h"
37 #include "vogl_buffer_state.h"
38 #include "vogl_fbo_state.h"
39 #include "vogl_sampler_state.h"
40 #include "vogl_shader_state.h"
41 #include "vogl_program_state.h"
42 #include "vogl_renderbuffer_state.h"
43 #include "vogl_query_state.h"
44 #include "vogl_vao_state.h"
45 #include "vogl_texenv_state.h"
46 #include "vogl_light_state.h"
47 #include "vogl_material_state.h"
48 #include "vogl_display_list_state.h"
49 #include "vogl_matrix_state.h"
50 #include "vogl_current_vertex_attrib_state.h"
51 #include "vogl_arb_program_state.h"
52 #include "vogl_handle_tracker.h"
53 #include "vogl_default_framebuffer_state.h"
54
55 //----------------------------------------------------------------------------------------------------------------------
56 // Types
57 //----------------------------------------------------------------------------------------------------------------------
58 typedef vogl::hash_map<GLuint, GLenum> vogl_handle_hash_map;
59 typedef vogl::hash_map<GLuint> vogl_handle_hash_set;
60 typedef vogl::hash_map<uint64_t, empty_type> vogl_sync_hash_set;
61
62 //----------------------------------------------------------------------------------------------------------------------
63 // vogl_handle_to_sync
64 //----------------------------------------------------------------------------------------------------------------------
65 inline GLsync vogl_handle_to_sync(uint64_t handle)
66 {
67     GLsync sync = 0;
68     memcpy(&sync, &handle, math::minimum<uint>(sizeof(GLsync), sizeof(uint64_t)));
69     return sync;
70 }
71
72 //----------------------------------------------------------------------------------------------------------------------
73 // vogl_sync_to_handle
74 //----------------------------------------------------------------------------------------------------------------------
75 inline uint64_t vogl_sync_to_handle(GLsync sync)
76 {
77     uint64_t handle = 0;
78     memcpy(&handle, &sync, math::minimum<uint>(sizeof(GLsync), sizeof(uint64_t)));
79     return handle;
80 }
81
82 //----------------------------------------------------------------------------------------------------------------------
83 // class vogl_capture_context_params
84 // TODO: Rename this to vogl_context_state_shadow?
85 //----------------------------------------------------------------------------------------------------------------------
86 class vogl_capture_context_params
87 {
88 public:
89     vogl_capture_context_params()
90         : m_rbos(VOGL_NAMESPACE_RENDER_BUFFERS),
91           m_textures(VOGL_NAMESPACE_TEXTURES),
92           m_objs(VOGL_NAMESPACE_PROGRAMS),
93           m_filter_program_handles(false)
94     {
95         VOGL_FUNC_TRACER
96     }
97
98     void clear()
99     {
100         VOGL_FUNC_TRACER
101
102         m_query_targets.clear();
103         m_buffer_targets.clear();
104         m_samplers.clear();
105         m_vaos.clear();
106         m_syncs.clear();
107         m_framebuffers.clear();
108         m_display_lists.clear();
109         m_arb_program_targets.clear();
110
111         m_rbos.clear();
112         m_textures.clear();
113         m_objs.clear();
114
115         m_linked_programs.clear();
116
117         m_program_handles_filter.clear();
118         m_filter_program_handles = false;
119     }
120
121     // During tracing: All handles live in the tracing GL namespace (there is no replay namespace).
122     // During replay: Any handles here live in the actual GL namespace (i.e. the "replay" or native GL namespace, NOT the trace namespace).
123     vogl_handle_hash_map m_query_targets;
124     vogl_handle_hash_map m_buffer_targets;
125     vogl_handle_hash_set m_samplers;
126     vogl_handle_hash_set m_vaos;
127     vogl_sync_hash_set m_syncs;
128     vogl_handle_hash_set m_framebuffers;
129     vogl_handle_hash_map m_arb_program_targets;
130
131     // During replay: trace domain
132     vogl_display_list_state m_display_lists;
133
134     // During replay: replay domain
135     vogl_linked_program_state m_linked_programs;
136
137     // During replay: These objects map from trace (non-inv) to replay (inv).
138     // TODO: Transition ALL the above hash sets/maps to instances of vogl_handle_tracker.
139     vogl_handle_tracker m_rbos;
140     vogl_handle_tracker m_textures;
141     vogl_handle_tracker m_objs;
142
143     vogl_handle_hash_set m_program_handles_filter;
144     bool m_filter_program_handles;
145 };
146
147 //----------------------------------------------------------------------------------------------------------------------
148 // class vogl_state_snapshot
149 //----------------------------------------------------------------------------------------------------------------------
150 class vogl_context_snapshot
151 {
152     VOGL_NO_COPY_OR_ASSIGNMENT_OP(vogl_context_snapshot);
153
154 public:
155     vogl_context_snapshot();
156     ~vogl_context_snapshot();
157
158     void clear();
159
160     bool capture(const vogl_context_desc &desc, const vogl_context_info &info, const vogl_capture_context_params &capture_params, vogl_handle_remapper &remapper);
161
162     bool is_valid() const
163     {
164         return m_is_valid;
165     }
166
167     const vogl_context_desc &get_context_desc() const
168     {
169         return m_context_desc;
170     }
171     const vogl_context_info &get_context_info() const
172     {
173         return m_context_info;
174     }
175
176     bool remap_handles(vogl_handle_remapper &remapper);
177
178     const vogl_general_context_state &get_general_state() const
179     {
180         return m_general_state;
181     }
182     vogl_general_context_state &get_general_state()
183     {
184         return m_general_state;
185     }
186
187     const vogl_texenv_state &get_texenv_state() const
188     {
189         return m_texenv_state;
190     }
191     vogl_texenv_state &get_texenv_state()
192     {
193         return m_texenv_state;
194     }
195
196     const vogl_light_state &get_light_state() const
197     {
198         return m_light_state;
199     }
200     vogl_light_state &get_light_state()
201     {
202         return m_light_state;
203     }
204
205     const vogl_material_state &get_material_state() const
206     {
207         return m_material_state;
208     }
209     vogl_material_state &get_material_state()
210     {
211         return m_material_state;
212     }
213
214     const vogl_display_list_state &get_display_list_state() const
215     {
216         return m_display_list_state;
217     }
218     vogl_display_list_state &get_display_list_state()
219     {
220         return m_display_list_state;
221     }
222
223     const vogl_matrix_state &get_matrix_state() const
224     {
225         return m_matrix_state;
226     }
227     vogl_matrix_state &get_matrix_state()
228     {
229         return m_matrix_state;
230     }
231
232     const vogl_polygon_stipple_state &get_polygon_stipple_state() const
233     {
234         return m_polygon_stipple_state;
235     }
236     vogl_polygon_stipple_state &get_polygon_stipple_state()
237     {
238         return m_polygon_stipple_state;
239     }
240
241     const vogl_gl_object_state_ptr_vec &get_objects() const
242     {
243         return m_object_ptrs;
244     }
245     vogl_gl_object_state_ptr_vec &get_objects()
246     {
247         return m_object_ptrs;
248     }
249
250     const vogl_current_vertex_attrib_state &get_current_vertex_attrib_state() const
251     {
252         return m_current_vertex_attrib_state;
253     }
254     vogl_current_vertex_attrib_state &get_current_vertex_attrib_state()
255     {
256         return m_current_vertex_attrib_state;
257     }
258
259     const vogl_arb_program_environment_state &get_arb_program_environment_state() const
260     {
261         return m_arb_program_environment_state;
262     }
263     vogl_arb_program_environment_state &get_arb_program_environment_state()
264     {
265         return m_arb_program_environment_state;
266     }
267
268     void get_all_objects_of_category(vogl_gl_object_state_type state_type, vogl_gl_object_state_ptr_vec &obj_ptr_vec) const;
269
270     bool serialize(json_node &node, vogl_blob_manager &blob_manager, const vogl_ctypes *pCtypes) const;
271     bool deserialize(const json_node &node, const vogl_blob_manager &blob_manager, const vogl_ctypes *pCtypes);
272
273 private:
274     vogl_context_desc m_context_desc;
275     vogl_context_info m_context_info;
276
277     vogl_general_context_state m_general_state;
278     vogl_texenv_state m_texenv_state;
279     vogl_light_state m_light_state;
280     vogl_material_state m_material_state;
281     vogl_display_list_state m_display_list_state;
282     vogl_matrix_state m_matrix_state;
283     vogl_polygon_stipple_state m_polygon_stipple_state;
284     vogl_current_vertex_attrib_state m_current_vertex_attrib_state;
285     vogl_arb_program_environment_state m_arb_program_environment_state;
286
287     vogl_gl_object_state_ptr_vec m_object_ptrs;
288
289     bool capture_objects(vogl_gl_object_state_type state_type, const vogl_capture_context_params &capture_params, vogl_handle_remapper &remapper);
290
291     bool m_is_valid;
292
293     void destroy_objects();
294 };
295
296 typedef vogl::vector<vogl_context_snapshot *> vogl_context_snapshot_ptr_vec;
297
298 //----------------------------------------------------------------------------------------------------------------------
299 // struct vogl_client_side_array_desc
300 //----------------------------------------------------------------------------------------------------------------------
301 struct vogl_client_side_array_desc
302 {
303     vogl_client_side_array_desc()
304     {
305     }
306     vogl_client_side_array_desc(vogl_trace_ptr_value ptr, uint size)
307         : m_ptr(ptr), m_size(size)
308     {
309     }
310
311     void init(vogl_trace_ptr_value ptr, uint size)
312     {
313         m_ptr = ptr;
314         m_size = size;
315     }
316
317     vogl_trace_ptr_value m_ptr;
318     uint m_size;
319
320     bool serialize(json_node &node, vogl_blob_manager &blob_manager) const
321     {
322         VOGL_FUNC_TRACER
323
324         VOGL_NOTE_UNUSED(blob_manager);
325
326         node.add_key_value("ptr", m_ptr);
327         node.add_key_value("size", m_size);
328         return true;
329     }
330
331     bool deserialize(const json_node &node, const vogl_blob_manager &blob_manager)
332     {
333         VOGL_FUNC_TRACER
334
335         VOGL_NOTE_UNUSED(blob_manager);
336
337         m_ptr = node.value_as_uint64("ptr");
338         m_size = node.value_as_uint32("size");
339         return true;
340     }
341 };
342
343 typedef vogl::vector<vogl_client_side_array_desc> vogl_client_side_array_desc_vec;
344
345 //----------------------------------------------------------------------------------------------------------------------
346 // class vogl_gl_state_snapshot
347 //----------------------------------------------------------------------------------------------------------------------
348 class vogl_gl_state_snapshot
349 {
350     VOGL_NO_COPY_OR_ASSIGNMENT_OP(vogl_gl_state_snapshot);
351
352 public:
353     vogl_gl_state_snapshot();
354     ~vogl_gl_state_snapshot();
355
356     void clear();
357
358     // frame_index indicates the beginning of frame X, at a swap boundary
359     bool begin_capture(uint window_width, uint window_height, vogl_trace_ptr_value cur_context, uint frame_index, int64_t gl_call_counter, bool at_frame_boundary);
360
361     void add_client_side_array_ptrs(const vogl_client_side_array_desc_vec &client_side_vertex_attrib_ptrs, const vogl_client_side_array_desc_vec &client_side_array_ptrs, const vogl_client_side_array_desc_vec &client_side_texcoord_ptrs);
362
363     bool capture_context(
364         const vogl_context_desc &desc, const vogl_context_info &info, vogl_handle_remapper &remapper,
365         const vogl_capture_context_params &capture_params);
366
367     bool end_capture();
368
369     bool is_valid() const
370     {
371         return m_is_valid;
372     }
373
374     bool serialize(json_node &node, vogl_blob_manager &blob_manager, const vogl_ctypes *pCtypes) const;
375     bool deserialize(const json_node &node, const vogl_blob_manager &blob_manager, const vogl_ctypes *pCtypes);
376
377     md5_hash get_uuid() const
378     {
379         return m_uuid;
380     }
381     uint get_window_width() const
382     {
383         return m_window_width;
384     }
385     uint get_window_height() const
386     {
387         return m_window_height;
388     }
389     vogl_trace_ptr_value get_cur_trace_context() const
390     {
391         return m_cur_trace_context;
392     }
393
394     void set_frame_index(uint frame_index)
395     {
396         m_frame_index = frame_index;
397     }
398     uint get_frame_index() const
399     {
400         return m_frame_index;
401     }
402     int64_t get_gl_call_counter() const
403     {
404         return m_gl_call_counter;
405     }
406     bool get_at_frame_boundary() const
407     {
408         return m_at_frame_boundary;
409     }
410
411     bool get_is_restorable() const
412     {
413         return m_is_restorable;
414     }
415     void set_is_restorable(bool is_restorable)
416     {
417         m_is_restorable = is_restorable;
418     }
419
420     const vogl_client_side_array_desc_vec &get_client_side_vertex_attrib_ptrs() const
421     {
422         return m_client_side_vertex_attrib_ptrs;
423     }
424     const vogl_client_side_array_desc_vec &get_client_side_array_ptrs() const
425     {
426         return m_client_side_array_ptrs;
427     }
428     const vogl_client_side_array_desc_vec &get_client_side_texcoord_ptrs() const
429     {
430         return m_client_side_texcoord_ptrs;
431     }
432
433     const vogl_context_snapshot_ptr_vec &get_contexts() const
434     {
435         return m_context_ptrs;
436     }
437     vogl_context_snapshot_ptr_vec &get_contexts()
438     {
439         return m_context_ptrs;
440     }
441
442     const vogl_default_framebuffer_state &get_default_framebuffer() const
443     {
444         return m_default_framebuffer;
445     }
446     vogl_default_framebuffer_state &get_default_framebuffer()
447     {
448         return m_default_framebuffer;
449     }
450     
451     vogl_context_snapshot* get_context(vogl_trace_ptr_value contextHandle) const
452     {
453         for (vogl_context_snapshot_ptr_vec::const_iterator iter = m_context_ptrs.begin(); iter != m_context_ptrs.end(); iter++)
454         {
455             if ((*iter)->get_context_desc().get_trace_context() == contextHandle)
456             {
457                 return (*iter);
458             }
459         }
460         return NULL;
461     }
462
463 private:
464     md5_hash m_uuid;
465     uint m_window_width;
466     uint m_window_height;
467     vogl_trace_ptr_value m_cur_trace_context;
468     uint m_frame_index;
469     int64_t m_gl_call_counter;
470     bool m_at_frame_boundary;
471     bool m_is_restorable;
472
473     vogl_client_side_array_desc_vec m_client_side_vertex_attrib_ptrs;
474     vogl_client_side_array_desc_vec m_client_side_array_ptrs;
475     vogl_client_side_array_desc_vec m_client_side_texcoord_ptrs;
476
477     vogl_context_snapshot_ptr_vec m_context_ptrs;
478
479     vogl_default_framebuffer_state m_default_framebuffer;
480
481     bool m_captured_default_framebuffer;
482     bool m_is_valid;
483
484     void destroy_contexts()
485     {
486         for (uint i = 0; i < m_context_ptrs.size(); i++)
487             vogl_delete(m_context_ptrs[i]);
488         m_context_ptrs.clear();
489     }
490 };
491
492 namespace vogl
493 {
494     VOGL_DEFINE_BITWISE_MOVABLE(vogl_context_snapshot);
495     VOGL_DEFINE_BITWISE_MOVABLE(vogl_gl_state_snapshot);
496 }
497
498 #endif // VOGL_GL_STATE_SNAPSHOT_H