X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace%2Fglstate_images.cpp;h=37c0ae1da66907acdc4c4e50e4ee7714c5201301;hb=d67cc37dee7e0d60af2cd172fa135962a6dc3ce5;hp=759ed5925839d5479c3ad9d7a7612508efc4daad;hpb=05097765d41b9dba7d1796e54a4f4587c37fcdf0;p=apitrace diff --git a/retrace/glstate_images.cpp b/retrace/glstate_images.cpp index 759ed59..37c0ae1 100644 --- a/retrace/glstate_images.cpp +++ b/retrace/glstate_images.cpp @@ -59,11 +59,6 @@ OSStatus CGSGetSurfaceBounds(CGSConnectionID, CGWindowID, CGSSurfaceID, CGRect * #endif /* __APPLE__ */ -/* Change thi to one to force interpreting depth buffers as RGBA, which enables - * visualizing full dynamic range, until we can transmit HDR images to the GUI */ -#define DEPTH_AS_RGBA 0 - - namespace glstate { @@ -72,6 +67,7 @@ struct ImageDesc GLint width; GLint height; GLint depth; + GLint samples; GLint internalFormat; inline @@ -79,9 +75,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 +289,8 @@ getActiveTextureLevelDesc(Context &context, GLenum target, GLint level, ImageDes } } + glGetTexLevelParameteriv(target, level, GL_TEXTURE_SAMPLES, &desc.samples); + return desc.valid(); } @@ -379,23 +387,134 @@ getTexImageOES(GLenum target, GLint level, ImageDesc &desc, GLubyte *pixels) } -static inline GLboolean -isDepthFormat(GLenum internalFormat) +struct InternalFormatDesc +{ + GLenum internalFormat; + GLenum format; +}; + + +static const InternalFormatDesc +internalFormatDescs[] = { + + {1, GL_RED}, + {2, GL_RG}, + {3, GL_RGB}, + {4, GL_RGBA}, + + {GL_RED, GL_RED}, + {GL_GREEN, GL_GREEN}, + {GL_BLUE, GL_BLUE}, + {GL_ALPHA, GL_ALPHA}, + {GL_RG, GL_RG}, + {GL_RGB, GL_RGB}, + {GL_BGR, GL_RGB}, + {GL_RGBA, GL_RGBA}, + {GL_BGRA, GL_RGBA}, + {GL_LUMINANCE, GL_LUMINANCE}, + {GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA}, + {GL_INTENSITY, GL_INTENSITY}, + + {GL_RG8, GL_RG}, + {GL_RG16, GL_RG}, + {GL_RGB8, GL_RGB}, + {GL_RGB16, GL_RGB}, + {GL_RGBA8, GL_RGBA}, + {GL_RGBA16, GL_RGBA}, + {GL_RGB10_A2, GL_RGBA}, + {GL_LUMINANCE8, GL_LUMINANCE}, + {GL_LUMINANCE16, GL_LUMINANCE}, + {GL_ALPHA8, GL_ALPHA}, + {GL_ALPHA16, GL_ALPHA}, + {GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA}, + {GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA}, + {GL_INTENSITY8, GL_INTENSITY}, + {GL_INTENSITY16, GL_INTENSITY}, + + {GL_RED_INTEGER, GL_RED_INTEGER}, + {GL_GREEN_INTEGER, GL_GREEN_INTEGER}, + {GL_BLUE_INTEGER, GL_BLUE_INTEGER}, + {GL_ALPHA_INTEGER, GL_ALPHA_INTEGER}, + {GL_RG_INTEGER, GL_RG_INTEGER}, + {GL_RGB_INTEGER, GL_RGB_INTEGER}, + {GL_BGR_INTEGER, GL_RGB_INTEGER}, + {GL_RGBA_INTEGER, GL_RGBA_INTEGER}, + {GL_BGRA_INTEGER, GL_RGBA_INTEGER}, + {GL_LUMINANCE_INTEGER_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + + {GL_R8I, GL_RED_INTEGER}, + {GL_R8UI, GL_RED_INTEGER}, + {GL_R16I, GL_RED_INTEGER}, + {GL_R16UI, GL_RED_INTEGER}, + {GL_R32I, GL_RED_INTEGER}, + {GL_R32UI, GL_RED_INTEGER}, + {GL_RG8I, GL_RG_INTEGER}, + {GL_RG8UI, GL_RG_INTEGER}, + {GL_RG16I, GL_RG_INTEGER}, + {GL_RG16UI, GL_RG_INTEGER}, + {GL_RG32I, GL_RG_INTEGER}, + {GL_RG32UI, GL_RG_INTEGER}, + {GL_RGB8I, GL_RGB_INTEGER}, + {GL_RGB8UI, GL_RGB_INTEGER}, + {GL_RGB16I, GL_RGB_INTEGER}, + {GL_RGB16UI, GL_RGB_INTEGER}, + {GL_RGB32I, GL_RGB_INTEGER}, + {GL_RGB32UI, GL_RGB_INTEGER}, + {GL_RGBA8I, GL_RGBA_INTEGER}, + {GL_RGBA8UI, GL_RGBA_INTEGER}, + {GL_RGBA16I, GL_RGBA_INTEGER}, + {GL_RGBA16UI, GL_RGBA_INTEGER}, + {GL_RGBA32I, GL_RGBA_INTEGER}, + {GL_RGBA32UI, GL_RGBA_INTEGER}, + {GL_RGB10_A2UI, GL_RGBA_INTEGER}, + {GL_LUMINANCE8I_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE8UI_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE16I_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE16UI_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE32I_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE32UI_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_ALPHA8I_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA8UI_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA16I_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA16UI_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA32I_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA32UI_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA8I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA8UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA16I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA16UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA32I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_INTENSITY8I_EXT, GL_RED_INTEGER}, + {GL_INTENSITY8UI_EXT, GL_RED_INTEGER}, + {GL_INTENSITY16I_EXT, GL_RED_INTEGER}, + {GL_INTENSITY16UI_EXT, GL_RED_INTEGER}, + {GL_INTENSITY32I_EXT, GL_RED_INTEGER}, + {GL_INTENSITY32UI_EXT, GL_RED_INTEGER}, + + {GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT32F_NV, GL_DEPTH_COMPONENT}, + {GL_DEPTH_STENCIL, GL_DEPTH_COMPONENT}, + {GL_DEPTH24_STENCIL8, GL_DEPTH_COMPONENT}, + {GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT}, + {GL_DEPTH32F_STENCIL8_NV, GL_DEPTH_COMPONENT}, +}; + + +static GLenum +getFormat(GLenum internalFormat) { - switch (internalFormat) { - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - case GL_DEPTH_COMPONENT32F: - case GL_DEPTH_COMPONENT32F_NV: - case GL_DEPTH_STENCIL: - case GL_DEPTH24_STENCIL8: - case GL_DEPTH32F_STENCIL8: - case GL_DEPTH32F_STENCIL8_NV: - return GL_TRUE; - } - return GL_FALSE; + for (unsigned i = 0; i < sizeof internalFormatDescs / sizeof internalFormatDescs[0]; ++i) { + if (internalFormatDescs[i].internalFormat == internalFormat) { + return internalFormatDescs[i].format; + } + } + return GL_RGBA; } @@ -415,15 +534,11 @@ dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint json.beginMember(label); - GLuint channels; - GLenum format; - if (!context.ES && isDepthFormat(desc.internalFormat)) { - format = GL_DEPTH_COMPONENT; - channels = 1; - } else { - format = GL_RGBA; - channels = 4; + GLenum format = getFormat(desc.internalFormat);; + if (context.ES && format == GL_DEPTH_COMPONENT) { + format = GL_RED; } + GLuint channels = _gl_format_channels(format);; image::Image *image = new image::Image(desc.width, desc.height*desc.depth, channels, true); @@ -675,6 +790,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(); @@ -813,15 +930,15 @@ getDrawBufferImage() { } GLenum type = GL_UNSIGNED_BYTE; + image::ChannelType channelType = image::TYPE_UNORM8; -#if DEPTH_AS_RGBA if (format == GL_DEPTH_COMPONENT) { - type = GL_UNSIGNED_INT; - channels = 4; + type = GL_FLOAT; + channels = 1; + channelType = image::TYPE_FLOAT; } -#endif - image::Image *image = new image::Image(desc.width, desc.height, channels, true); + image::Image *image = new image::Image(desc.width, desc.height, channels, true, channelType); if (!image) { return NULL; } @@ -880,15 +997,15 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format, Context context; GLenum type = GL_UNSIGNED_BYTE; + image::ChannelType channelType = image::TYPE_UNORM8; -#if DEPTH_AS_RGBA if (format == GL_DEPTH_COMPONENT) { - type = GL_UNSIGNED_INT; - channels = 4; + type = GL_FLOAT; + channels = 1; + channelType = image::TYPE_FLOAT; } -#endif - image::Image *image = new image::Image(width, height, channels, true); + image::Image *image = new image::Image(width, height, channels, true, channelType); while (glGetError() != GL_NO_ERROR) {} @@ -917,7 +1034,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 +1049,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 +1059,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 +1091,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 +1106,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 +1196,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 +1264,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 +1271,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,7 +1301,7 @@ 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);