]> git.cworth.org Git - apitrace/blob - retrace/glstate.cpp
glstate: Dump more object labels.
[apitrace] / retrace / glstate.cpp
1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
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
27 #include <string.h>
28
29 #include <algorithm>
30 #include <iostream>
31
32 #include "image.hpp"
33 #include "json.hpp"
34 #include "glproc.hpp"
35 #include "glws.hpp"
36 #include "glsize.hpp"
37 #include "glstate.hpp"
38 #include "glstate_internal.hpp"
39
40
41 namespace glstate {
42
43
44 Context::Context(void) {
45     memset(this, 0, sizeof *this);
46
47     const char *version = (const char *)glGetString(GL_VERSION);
48     unsigned version_major = 0;
49     unsigned version_minor = 0;
50     unsigned version_release = 0;
51     if (version) {
52         if (version[0] == 'O' &&
53             version[1] == 'p' &&
54             version[2] == 'e' &&
55             version[3] == 'n' &&
56             version[4] == 'G' &&
57             version[5] == 'L' &&
58             version[6] == ' ' &&
59             version[7] == 'E' &&
60             version[8] == 'S' &&
61             (version[9] == ' ' || version[9] == '-')) {
62             ES = true;
63         }
64         if (version[0] >= '0' && version[0] <= '9') {
65             sscanf(version, "%u.%u.%u", &version_major, &version_minor, &version_release);
66         }
67     }
68
69     ARB_draw_buffers = !ES;
70
71     // Check extensions we use.
72
73     if (!ES) {
74         if (version_major > 3 ||
75             (version_major == 3 && version_minor >= 2)) {
76             GLint num_extensions = 0;
77             glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
78             for (GLint i = 0; i < num_extensions; ++i) {
79                const char *extension = (const char *)glGetStringi(GL_EXTENSIONS, i);
80                if (extension) {
81                    if (strcmp(extension, "GL_ARB_sampler_objects") == 0) {
82                        ARB_sampler_objects = true;
83                    } else if (strcmp(extension, "GL_KHR_debug") == 0) {
84                        KHR_debug = true;
85                    }
86                }
87             }
88         } else {
89             const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
90             ARB_sampler_objects = glws::checkExtension("GL_ARB_sampler_objects", extensions);
91             KHR_debug = glws::checkExtension("GL_KHR_debug", extensions);
92         }
93     } else {
94         const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
95         KHR_debug = glws::checkExtension("GL_KHR_debug", extensions);
96     }
97 }
98
99 void
100 Context::resetPixelPackState(void) {
101     // Start with default state
102     pack_alignment = 4;
103     pack_image_height = 0;
104     pack_lsb_first = GL_FALSE;
105     pack_row_length = 0;
106     pack_skip_images = 0;
107     pack_skip_pixels = 0;
108     pack_skip_rows = 0;
109     pack_swap_bytes = GL_FALSE;
110     pixel_pack_buffer_binding = 0;
111
112     // Get current state
113     glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
114     if (!ES) {
115         glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &pack_image_height);
116         glGetIntegerv(GL_PACK_LSB_FIRST, &pack_lsb_first);
117         glGetIntegerv(GL_PACK_ROW_LENGTH, &pack_row_length);
118         glGetIntegerv(GL_PACK_SKIP_IMAGES, &pack_skip_images);
119         glGetIntegerv(GL_PACK_SKIP_PIXELS, &pack_skip_pixels);
120         glGetIntegerv(GL_PACK_SKIP_ROWS, &pack_skip_rows);
121         glGetIntegerv(GL_PACK_SWAP_BYTES, &pack_swap_bytes);
122         glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &pixel_pack_buffer_binding);
123     }
124
125     // Reset state for compact images
126     glPixelStorei(GL_PACK_ALIGNMENT, 1);
127     if (!ES) {
128         glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
129         glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
130         glPixelStorei(GL_PACK_ROW_LENGTH, 0);
131         glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
132         glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
133         glPixelStorei(GL_PACK_SKIP_ROWS, 0);
134         glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
135         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
136     }
137 }
138
139 void
140 Context::restorePixelPackState(void) {
141     glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
142     if (!ES) {
143         glPixelStorei(GL_PACK_IMAGE_HEIGHT, pack_image_height);
144         glPixelStorei(GL_PACK_LSB_FIRST, pack_lsb_first);
145         glPixelStorei(GL_PACK_ROW_LENGTH, pack_row_length);
146         glPixelStorei(GL_PACK_SKIP_IMAGES, pack_skip_images);
147         glPixelStorei(GL_PACK_SKIP_PIXELS, pack_skip_pixels);
148         glPixelStorei(GL_PACK_SKIP_ROWS, pack_skip_rows);
149         glPixelStorei(GL_PACK_SWAP_BYTES, pack_swap_bytes);
150         glBindBuffer(GL_PIXEL_PACK_BUFFER, pixel_pack_buffer_binding);
151     }
152 }
153
154
155 /**
156  * Dump a GL_KHR_debug object label.
157  */
158 void
159 dumpObjectLabel(JSONWriter &json, Context &context, GLenum identifier, GLuint name, const char *member)
160 {
161     if (!name) {
162         return;
163     }
164
165     if (!context.KHR_debug) {
166         return;
167     }
168
169     GLsizei length = 0;
170     glGetObjectLabel(identifier, name, 0, &length, NULL);
171     if (!length) {
172         return;
173     }
174
175     char *label = (char *)malloc(length);
176     if (!label) {
177         return;
178     }
179
180     glGetObjectLabel(identifier, name, length, NULL, label);
181
182     json.writeStringMember(member, label);
183
184     free(label);
185 }
186
187
188 static const GLenum bindings[] = {
189     GL_DRAW_BUFFER,
190     GL_READ_BUFFER,
191     GL_PIXEL_PACK_BUFFER_BINDING,
192     GL_PIXEL_UNPACK_BUFFER_BINDING,
193     GL_TEXTURE_BINDING_1D,
194     GL_TEXTURE_BINDING_1D_ARRAY,
195     GL_TEXTURE_BINDING_2D,
196     GL_TEXTURE_BINDING_2D_ARRAY,
197     GL_TEXTURE_BINDING_2D_MULTISAMPLE,
198     GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY,
199     GL_TEXTURE_BINDING_3D,
200     GL_TEXTURE_BINDING_RECTANGLE,
201     GL_TEXTURE_BINDING_CUBE_MAP,
202     GL_TEXTURE_BINDING_CUBE_MAP_ARRAY,
203     GL_DRAW_FRAMEBUFFER_BINDING,
204     GL_READ_FRAMEBUFFER_BINDING,
205     GL_RENDERBUFFER_BINDING,
206     GL_DRAW_BUFFER0,
207     GL_DRAW_BUFFER1,
208     GL_DRAW_BUFFER2,
209     GL_DRAW_BUFFER3,
210     GL_DRAW_BUFFER4,
211     GL_DRAW_BUFFER5,
212     GL_DRAW_BUFFER6,
213     GL_DRAW_BUFFER7,
214 };
215
216
217 #define NUM_BINDINGS sizeof(bindings)/sizeof(bindings[0])
218
219
220 void dumpCurrentContext(std::ostream &os)
221 {
222     JSONWriter json(os);
223
224 #ifndef NDEBUG
225     GLint old_bindings[NUM_BINDINGS];
226     for (unsigned i = 0; i < NUM_BINDINGS; ++i) {
227         old_bindings[i] = 0;
228         glGetIntegerv(bindings[i], &old_bindings[i]);
229     }
230 #endif
231
232     Context context;
233
234     dumpParameters(json, context);
235     dumpShadersUniforms(json, context);
236     dumpTextures(json, context);
237     dumpFramebuffer(json, context);
238
239 #ifndef NDEBUG
240     for (unsigned i = 0; i < NUM_BINDINGS; ++i) {
241         GLint new_binding = 0;
242         glGetIntegerv(bindings[i], &new_binding);
243         if (new_binding != old_bindings[i]) {
244             std::cerr << "warning: " << enumToString(bindings[i]) << " was clobbered\n";
245         }
246     }
247 #endif
248
249 }
250
251
252 } /* namespace glstate */