]> git.cworth.org Git - apitrace/blobdiff - retrace/glstate.cpp
retrace: Implement glxCopySubBufferMESA
[apitrace] / retrace / glstate.cpp
index 0d5a5f3bd629ec2677451098f44060ad5d4525c6..8c1bec9f55cd772e98fc8df3624836f482477717 100644 (file)
@@ -32,6 +32,7 @@
 #include "image.hpp"
 #include "json.hpp"
 #include "glproc.hpp"
+#include "glws.hpp"
 #include "glsize.hpp"
 #include "glstate.hpp"
 #include "glstate_internal.hpp"
@@ -44,6 +45,9 @@ Context::Context(void) {
     memset(this, 0, sizeof *this);
 
     const char *version = (const char *)glGetString(GL_VERSION);
+    unsigned version_major = 0;
+    unsigned version_minor = 0;
+    unsigned version_release = 0;
     if (version) {
         if (version[0] == 'O' &&
             version[1] == 'p' &&
@@ -57,39 +61,127 @@ Context::Context(void) {
             (version[9] == ' ' || version[9] == '-')) {
             ES = true;
         }
+        if (version[0] >= '0' && version[0] <= '9') {
+            sscanf(version, "%u.%u.%u", &version_major, &version_minor, &version_release);
+        }
     }
 
     ARB_draw_buffers = !ES;
 
-    // TODO: Check extensions we use below
+    // Check extensions we use.
+
+    if (!ES) {
+        if (version_major > 3 ||
+            (version_major == 3 && version_minor >= 2)) {
+            GLint num_extensions = 0;
+            glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
+            for (GLint i = 0; i < num_extensions; ++i) {
+               const char *extension = (const char *)glGetStringi(GL_EXTENSIONS, i);
+               if (extension) {
+                   if (strcmp(extension, "GL_ARB_sampler_objects") == 0) {
+                       ARB_sampler_objects = true;
+                   } else if (strcmp(extension, "GL_KHR_debug") == 0) {
+                       KHR_debug = true;
+                   }
+               }
+            }
+        } else {
+            const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
+            ARB_sampler_objects = glws::checkExtension("GL_ARB_sampler_objects", extensions);
+            KHR_debug = glws::checkExtension("GL_KHR_debug", extensions);
+        }
+    } else {
+        const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
+        KHR_debug = glws::checkExtension("GL_KHR_debug", extensions);
+    }
 }
 
 void
 Context::resetPixelPackState(void) {
+    // Start with default state
+    pack_alignment = 4;
+    pack_image_height = 0;
+    pack_lsb_first = GL_FALSE;
+    pack_row_length = 0;
+    pack_skip_images = 0;
+    pack_skip_pixels = 0;
+    pack_skip_rows = 0;
+    pack_swap_bytes = GL_FALSE;
+    pixel_pack_buffer_binding = 0;
+
+    // Get current state
+    glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
     if (!ES) {
-        glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
-        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-        glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
+        glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &pack_image_height);
+        glGetIntegerv(GL_PACK_LSB_FIRST, &pack_lsb_first);
+        glGetIntegerv(GL_PACK_ROW_LENGTH, &pack_row_length);
+        glGetIntegerv(GL_PACK_SKIP_IMAGES, &pack_skip_images);
+        glGetIntegerv(GL_PACK_SKIP_PIXELS, &pack_skip_pixels);
+        glGetIntegerv(GL_PACK_SKIP_ROWS, &pack_skip_rows);
+        glGetIntegerv(GL_PACK_SWAP_BYTES, &pack_swap_bytes);
+        glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &pixel_pack_buffer_binding);
+    }
+
+    // Reset state for compact images
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    if (!ES) {
+        glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
         glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
         glPixelStorei(GL_PACK_ROW_LENGTH, 0);
-        glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
-        glPixelStorei(GL_PACK_SKIP_ROWS, 0);
-        glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
         glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
-    } else {
-        packAlignment = 4;
-        glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
+        glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+        glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+        glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
     }
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
 }
 
 void
 Context::restorePixelPackState(void) {
+    glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
     if (!ES) {
-        glPopClientAttrib();
-    } else {
-        glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
+        glPixelStorei(GL_PACK_IMAGE_HEIGHT, pack_image_height);
+        glPixelStorei(GL_PACK_LSB_FIRST, pack_lsb_first);
+        glPixelStorei(GL_PACK_ROW_LENGTH, pack_row_length);
+        glPixelStorei(GL_PACK_SKIP_IMAGES, pack_skip_images);
+        glPixelStorei(GL_PACK_SKIP_PIXELS, pack_skip_pixels);
+        glPixelStorei(GL_PACK_SKIP_ROWS, pack_skip_rows);
+        glPixelStorei(GL_PACK_SWAP_BYTES, pack_swap_bytes);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, pixel_pack_buffer_binding);
+    }
+}
+
+
+/**
+ * Dump a GL_KHR_debug object label.
+ */
+void
+dumpObjectLabel(JSONWriter &json, Context &context, GLenum identifier, GLuint name, const char *member)
+{
+    if (!name) {
+        return;
     }
+
+    if (!context.KHR_debug) {
+        return;
+    }
+
+    GLsizei length = 0;
+    glGetObjectLabel(identifier, name, 0, &length, NULL);
+    if (!length) {
+        return;
+    }
+
+    char *label = (char *)malloc(length + 1);
+    if (!label) {
+        return;
+    }
+
+    glGetObjectLabel(identifier, name, length + 1, NULL, label);
+
+    json.writeStringMember(member, label);
+
+    free(label);
 }
 
 
@@ -99,10 +191,15 @@ static const GLenum bindings[] = {
     GL_PIXEL_PACK_BUFFER_BINDING,
     GL_PIXEL_UNPACK_BUFFER_BINDING,
     GL_TEXTURE_BINDING_1D,
+    GL_TEXTURE_BINDING_1D_ARRAY,
     GL_TEXTURE_BINDING_2D,
+    GL_TEXTURE_BINDING_2D_ARRAY,
+    GL_TEXTURE_BINDING_2D_MULTISAMPLE,
+    GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY,
     GL_TEXTURE_BINDING_3D,
     GL_TEXTURE_BINDING_RECTANGLE,
     GL_TEXTURE_BINDING_CUBE_MAP,
+    GL_TEXTURE_BINDING_CUBE_MAP_ARRAY,
     GL_DRAW_FRAMEBUFFER_BINDING,
     GL_READ_FRAMEBUFFER_BINDING,
     GL_RENDERBUFFER_BINDING,