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