]> git.cworth.org Git - apitrace/blobdiff - retrace/glstate_images.cpp
glstate: Better support for integer textures dumps.
[apitrace] / retrace / glstate_images.cpp
index f0b4eddb15d3bdded2a3e3efaefe4c782dd2d609..0fcc9d82d89696e5ff8c350c461fc9240b700c26 100644 (file)
@@ -72,6 +72,7 @@ struct ImageDesc
     GLint width;
     GLint height;
     GLint depth;
+    GLint samples;
     GLint internalFormat;
 
     inline
@@ -79,9 +80,19 @@ struct ImageDesc
         width(0),
         height(0),
         depth(0),
+        samples(0),
         internalFormat(GL_NONE)
     {}
 
+    inline bool
+    operator == (const ImageDesc &other) const {
+        return width == other.width &&
+               height == other.height &&
+               depth == other.depth &&
+               samples == other.samples &&
+               internalFormat == other.internalFormat;
+    }
+
     inline bool
     valid(void) const {
         return width > 0 && height > 0 && depth > 0;
@@ -283,6 +294,8 @@ getActiveTextureLevelDesc(Context &context, GLenum target, GLint level, ImageDes
         }
     }
 
+    glGetTexLevelParameteriv(target, level, GL_TEXTURE_SAMPLES, &desc.samples);
+
     return desc.valid();
 }
 
@@ -399,6 +412,78 @@ isDepthFormat(GLenum internalFormat)
 }
 
 
+static inline GLboolean
+isIntegerFormat(GLenum internalFormat)
+{
+   switch (internalFormat) {
+
+   case GL_RG_INTEGER:
+   case GL_RED_INTEGER:
+   case GL_GREEN_INTEGER:
+   case GL_BLUE_INTEGER:
+   case GL_ALPHA_INTEGER:
+   case GL_RGB_INTEGER:
+   case GL_RGBA_INTEGER:
+   case GL_BGR_INTEGER:
+   case GL_BGRA_INTEGER:
+   case GL_LUMINANCE_INTEGER_EXT:
+   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+
+   case GL_R8I:
+   case GL_R8UI:
+   case GL_R16I:
+   case GL_R16UI:
+   case GL_R32I:
+   case GL_R32UI:
+   case GL_RG8I:
+   case GL_RG8UI:
+   case GL_RG16I:
+   case GL_RG16UI:
+   case GL_RG32I:
+   case GL_RG32UI:
+   case GL_RGB8I:
+   case GL_RGB8UI:
+   case GL_RGB16I:
+   case GL_RGB16UI:
+   case GL_RGB32I:
+   case GL_RGB32UI:
+   case GL_RGBA8I:
+   case GL_RGBA8UI:
+   case GL_RGBA16I:
+   case GL_RGBA16UI:
+   case GL_RGBA32I:
+   case GL_RGBA32UI:
+   case GL_RGB10_A2UI:
+   case GL_LUMINANCE8I_EXT:
+   case GL_LUMINANCE8UI_EXT:
+   case GL_LUMINANCE16I_EXT:
+   case GL_LUMINANCE16UI_EXT:
+   case GL_LUMINANCE32I_EXT:
+   case GL_LUMINANCE32UI_EXT:
+   case GL_ALPHA8I_EXT:
+   case GL_ALPHA8UI_EXT:
+   case GL_ALPHA16I_EXT:
+   case GL_ALPHA16UI_EXT:
+   case GL_ALPHA32I_EXT:
+   case GL_ALPHA32UI_EXT:
+   case GL_LUMINANCE_ALPHA8I_EXT:
+   case GL_LUMINANCE_ALPHA8UI_EXT:
+   case GL_LUMINANCE_ALPHA16I_EXT:
+   case GL_LUMINANCE_ALPHA16UI_EXT:
+   case GL_LUMINANCE_ALPHA32I_EXT:
+   case GL_LUMINANCE_ALPHA32UI_EXT:
+   case GL_INTENSITY8I_EXT:
+   case GL_INTENSITY8UI_EXT:
+   case GL_INTENSITY16I_EXT:
+   case GL_INTENSITY16UI_EXT:
+   case GL_INTENSITY32I_EXT:
+   case GL_INTENSITY32UI_EXT:
+      return GL_TRUE;
+   }
+   return GL_FALSE;
+}
+
+
 static inline void
 dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint level)
 {
@@ -418,11 +503,15 @@ dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint
     GLuint channels;
     GLenum format;
     if (!context.ES && isDepthFormat(desc.internalFormat)) {
-       format = GL_DEPTH_COMPONENT;
-       channels = 1;
+        format = GL_DEPTH_COMPONENT;
+        channels = 1;
     } else {
-       format = GL_RGBA;
-       channels = 4;
+        if (isIntegerFormat(desc.internalFormat)) {
+            format = GL_RGBA_INTEGER;
+        } else {
+            format = GL_RGBA;
+        }
+        channels = 4;
     }
 
     image::Image *image = new image::Image(desc.width, desc.height*desc.depth, channels, true);
@@ -675,6 +764,8 @@ getBoundRenderbufferDesc(Context &context, ImageDesc &desc)
     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &desc.height);
     desc.depth = 1;
     
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &desc.samples);
+
     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &desc.internalFormat);
     
     return desc.valid();
@@ -917,7 +1008,9 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format,
 static inline GLuint
 downsampledFramebuffer(Context &context,
                        GLuint oldFbo, GLint drawbuffer,
-                       GLint colorRb, GLint depthRb, GLint stencilRb,
+                       const ImageDesc &colorDesc,
+                       const ImageDesc &depthDesc,
+                       const ImageDesc &stencilDesc,
                        GLuint *rbs, GLint *numRbs)
 {
     GLuint fbo;
@@ -930,13 +1023,9 @@ downsampledFramebuffer(Context &context,
 
     {
         // color buffer
-        ImageDesc desc;
-        glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
-        getBoundRenderbufferDesc(context, desc);
-
         glGenRenderbuffers(1, &rbs[*numRbs]);
         glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
-        glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height);
+        glRenderbufferStorage(GL_RENDERBUFFER, colorDesc.internalFormat, colorDesc.width, colorDesc.height);
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer,
                                   GL_RENDERBUFFER, rbs[*numRbs]);
 
@@ -944,38 +1033,31 @@ downsampledFramebuffer(Context &context,
         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
         glDrawBuffer(drawbuffer);
         glReadBuffer(drawbuffer);
-        glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height,
+        glBlitFramebuffer(0, 0, colorDesc.width, colorDesc.height, 0, 0, colorDesc.width, colorDesc.height,
                           GL_COLOR_BUFFER_BIT, GL_NEAREST);
         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
         ++*numRbs;
     }
 
-    if (stencilRb == depthRb && stencilRb) {
+    if (stencilDesc == depthDesc &&
+        depthDesc.valid()) {
         //combined depth and stencil buffer
-        ImageDesc desc;
-        glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
-        getBoundRenderbufferDesc(context, desc);
-
         glGenRenderbuffers(1, &rbs[*numRbs]);
         glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
-        glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height);
+        glRenderbufferStorage(GL_RENDERBUFFER, depthDesc.internalFormat, depthDesc.width, depthDesc.height);
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
                                   GL_RENDERBUFFER, rbs[*numRbs]);
         glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
-        glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height,
+        glBlitFramebuffer(0, 0, depthDesc.width, depthDesc.height, 0, 0, depthDesc.width, depthDesc.height,
                           GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
         ++*numRbs;
     } else {
-        if (depthRb) {
-            ImageDesc desc;
-            glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
-            getBoundRenderbufferDesc(context, desc);
-
+        if (depthDesc.valid()) {
             glGenRenderbuffers(1, &rbs[*numRbs]);
             glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
-            glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height);
+            glRenderbufferStorage(GL_RENDERBUFFER, depthDesc.internalFormat, depthDesc.width, depthDesc.height);
             glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                                       GL_DEPTH_ATTACHMENT,
                                       GL_RENDERBUFFER, rbs[*numRbs]);
@@ -983,18 +1065,14 @@ downsampledFramebuffer(Context &context,
             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
             glDrawBuffer(GL_DEPTH_ATTACHMENT);
             glReadBuffer(GL_DEPTH_ATTACHMENT);
-            glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height,
+            glBlitFramebuffer(0, 0, depthDesc.width, depthDesc.height, 0, 0, depthDesc.width, depthDesc.height,
                               GL_DEPTH_BUFFER_BIT, GL_NEAREST);
             ++*numRbs;
         }
-        if (stencilRb) {
-            ImageDesc desc;
-            glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
-            getBoundRenderbufferDesc(context, desc);
-
+        if (stencilDesc.valid()) {
             glGenRenderbuffers(1, &rbs[*numRbs]);
             glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
-            glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height);
+            glRenderbufferStorage(GL_RENDERBUFFER, stencilDesc.internalFormat, stencilDesc.width, stencilDesc.height);
             glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                                       GL_STENCIL_ATTACHMENT,
                                       GL_RENDERBUFFER, rbs[*numRbs]);
@@ -1002,7 +1080,7 @@ downsampledFramebuffer(Context &context,
             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
             glDrawBuffer(GL_STENCIL_ATTACHMENT);
             glReadBuffer(GL_STENCIL_ATTACHMENT);
-            glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height,
+            glBlitFramebuffer(0, 0, stencilDesc.width, stencilDesc.height, 0, 0, stencilDesc.width, stencilDesc.height,
                               GL_STENCIL_BUFFER_BIT, GL_NEAREST);
             ++*numRbs;
         }
@@ -1092,6 +1170,8 @@ dumpFramebufferAttachment(JSONWriter &json, Context &context, GLenum target, GLe
         return;
     }
 
+    assert(desc.samples == 0);
+
     json.beginMember(enumToString(attachment));
     dumpReadBufferImage(json, desc.width, desc.height, format, desc.internalFormat);
     json.endMember();
@@ -1158,7 +1238,6 @@ dumpFramebuffer(JSONWriter &json, Context &context)
     } else if (context.ES) {
         dumpFramebufferAttachments(json, context, GL_FRAMEBUFFER);
     } else {
-        GLint colorRb = 0, stencilRb = 0, depthRb = 0;
         GLint draw_buffer0 = GL_NONE;
         glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer0);
         bool multisample = false;
@@ -1166,42 +1245,27 @@ dumpFramebuffer(JSONWriter &json, Context &context)
         GLint boundRb = 0;
         glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);
 
-        GLint object_type;
-        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
-        if (object_type == GL_RENDERBUFFER) {
-            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &colorRb);
-            glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
-            GLint samples = 0;
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
-            if (samples) {
+        ImageDesc colorDesc;
+        if (getFramebufferAttachmentDesc(context, GL_DRAW_FRAMEBUFFER, draw_buffer0, colorDesc)) {
+            if (colorDesc.samples) {
                 multisample = true;
             }
         }
 
-        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
-        if (object_type == GL_RENDERBUFFER) {
-            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthRb);
-            glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
-            GLint samples = 0;
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
-            if (samples) {
+        ImageDesc depthDesc;
+        if (getFramebufferAttachmentDesc(context, GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthDesc)) {
+            if (depthDesc.samples) {
                 multisample = true;
             }
         }
 
-        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
-        if (object_type == GL_RENDERBUFFER) {
-            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &stencilRb);
-            glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
-            GLint samples = 0;
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
-            if (samples) {
+        ImageDesc stencilDesc;
+        if (getFramebufferAttachmentDesc(context, GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, stencilDesc)) {
+            if (stencilDesc.samples) {
                 multisample = true;
             }
         }
 
-        glBindRenderbuffer(GL_RENDERBUFFER, boundRb);
-
         GLuint rbs[3];
         GLint numRbs = 0;
         GLuint fboCopy = 0;
@@ -1211,14 +1275,16 @@ dumpFramebuffer(JSONWriter &json, Context &context)
             // to blit the fbo to a temporary one
             fboCopy = downsampledFramebuffer(context,
                                              boundDrawFbo, draw_buffer0,
-                                             colorRb, depthRb, stencilRb,
+                                             colorDesc, depthDesc, stencilDesc,
                                              rbs, &numRbs);
+        } else {
+            glBindFramebuffer(GL_READ_FRAMEBUFFER, boundDrawFbo);
         }
 
-        dumpFramebufferAttachments(json, context, GL_DRAW_FRAMEBUFFER);
+        dumpFramebufferAttachments(json, context, GL_READ_FRAMEBUFFER);
 
         if (multisample) {
-            glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);
+            glBindRenderbuffer(GL_RENDERBUFFER, boundRb);
             glDeleteRenderbuffers(numRbs, rbs);
             glDeleteFramebuffers(1, &fboCopy);
         }