]> git.cworth.org Git - apitrace/blob - retrace/glstate.cpp
Check for ARB_sampler_objects before dumping its state.
[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                    strcmp(extension, "ARB_sampler_objects")) {
82                    ARB_sampler_objects = true;
83                }
84             }
85         } else {
86             const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
87             if (glws::checkExtension("ARB_sampler_objects", extensions)) {
88                 ARB_sampler_objects = true;
89             }
90         }
91     }
92 }
93
94 void
95 Context::resetPixelPackState(void) {
96     // Start with default state
97     pack_alignment = 4;
98     pack_image_height = 0;
99     pack_lsb_first = GL_FALSE;
100     pack_row_length = 0;
101     pack_skip_images = 0;
102     pack_skip_pixels = 0;
103     pack_skip_rows = 0;
104     pack_swap_bytes = GL_FALSE;
105     pixel_pack_buffer_binding = 0;
106
107     // Get current state
108     glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
109     if (!ES) {
110         glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &pack_image_height);
111         glGetIntegerv(GL_PACK_LSB_FIRST, &pack_lsb_first);
112         glGetIntegerv(GL_PACK_ROW_LENGTH, &pack_row_length);
113         glGetIntegerv(GL_PACK_SKIP_IMAGES, &pack_skip_images);
114         glGetIntegerv(GL_PACK_SKIP_PIXELS, &pack_skip_pixels);
115         glGetIntegerv(GL_PACK_SKIP_ROWS, &pack_skip_rows);
116         glGetIntegerv(GL_PACK_SWAP_BYTES, &pack_swap_bytes);
117         glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &pixel_pack_buffer_binding);
118     }
119
120     // Reset state for compact images
121     glPixelStorei(GL_PACK_ALIGNMENT, 1);
122     if (!ES) {
123         glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
124         glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
125         glPixelStorei(GL_PACK_ROW_LENGTH, 0);
126         glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
127         glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
128         glPixelStorei(GL_PACK_SKIP_ROWS, 0);
129         glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
130         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
131     }
132 }
133
134 void
135 Context::restorePixelPackState(void) {
136     glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
137     if (!ES) {
138         glPixelStorei(GL_PACK_IMAGE_HEIGHT, pack_image_height);
139         glPixelStorei(GL_PACK_LSB_FIRST, pack_lsb_first);
140         glPixelStorei(GL_PACK_ROW_LENGTH, pack_row_length);
141         glPixelStorei(GL_PACK_SKIP_IMAGES, pack_skip_images);
142         glPixelStorei(GL_PACK_SKIP_PIXELS, pack_skip_pixels);
143         glPixelStorei(GL_PACK_SKIP_ROWS, pack_skip_rows);
144         glPixelStorei(GL_PACK_SWAP_BYTES, pack_swap_bytes);
145         glBindBuffer(GL_PIXEL_PACK_BUFFER, pixel_pack_buffer_binding);
146     }
147 }
148
149
150 static const GLenum bindings[] = {
151     GL_DRAW_BUFFER,
152     GL_READ_BUFFER,
153     GL_PIXEL_PACK_BUFFER_BINDING,
154     GL_PIXEL_UNPACK_BUFFER_BINDING,
155     GL_TEXTURE_BINDING_1D,
156     GL_TEXTURE_BINDING_1D_ARRAY,
157     GL_TEXTURE_BINDING_2D,
158     GL_TEXTURE_BINDING_2D_ARRAY,
159     GL_TEXTURE_BINDING_2D_MULTISAMPLE,
160     GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY,
161     GL_TEXTURE_BINDING_3D,
162     GL_TEXTURE_BINDING_RECTANGLE,
163     GL_TEXTURE_BINDING_CUBE_MAP,
164     GL_TEXTURE_BINDING_CUBE_MAP_ARRAY,
165     GL_DRAW_FRAMEBUFFER_BINDING,
166     GL_READ_FRAMEBUFFER_BINDING,
167     GL_RENDERBUFFER_BINDING,
168     GL_DRAW_BUFFER0,
169     GL_DRAW_BUFFER1,
170     GL_DRAW_BUFFER2,
171     GL_DRAW_BUFFER3,
172     GL_DRAW_BUFFER4,
173     GL_DRAW_BUFFER5,
174     GL_DRAW_BUFFER6,
175     GL_DRAW_BUFFER7,
176 };
177
178
179 #define NUM_BINDINGS sizeof(bindings)/sizeof(bindings[0])
180
181
182 void dumpCurrentContext(std::ostream &os)
183 {
184     JSONWriter json(os);
185
186 #ifndef NDEBUG
187     GLint old_bindings[NUM_BINDINGS];
188     for (unsigned i = 0; i < NUM_BINDINGS; ++i) {
189         old_bindings[i] = 0;
190         glGetIntegerv(bindings[i], &old_bindings[i]);
191     }
192 #endif
193
194     Context context;
195
196     dumpParameters(json, context);
197     dumpShadersUniforms(json, context);
198     dumpTextures(json, context);
199     dumpFramebuffer(json, context);
200
201 #ifndef NDEBUG
202     for (unsigned i = 0; i < NUM_BINDINGS; ++i) {
203         GLint new_binding = 0;
204         glGetIntegerv(bindings[i], &new_binding);
205         if (new_binding != old_bindings[i]) {
206             std::cerr << "warning: " << enumToString(bindings[i]) << " was clobbered\n";
207         }
208     }
209 #endif
210
211 }
212
213
214 } /* namespace glstate */