Skip to content
Permalink
Browse files

Merge pull request #12125 from unknownbrackets/debugger

Debugger: Fix subtexture readback crash
  • Loading branch information...
hrydgard committed Jun 24, 2019
2 parents bf84945 + 7b8d3e0 commit 44685a7318887873f9655e694881f2f2a4c4e848
Showing with 49 additions and 14 deletions.
  1. +8 −0 GPU/Common/GPUStateUtils.cpp
  2. +41 −14 ext/native/thin3d/GLQueueRunner.cpp
@@ -1246,6 +1246,10 @@ static void ConvertStencilFunc5551(GenericStencilFuncState &state) {
state.testRef = usedRef;
// Nuke the mask as well, since this is always/never, just for consistency.
state.testMask = 0xFF;
} else {
// Not used, so let's make the ref 0xFF which is a useful value later.
state.testRef = 0xFF;
state.testMask = 0xFF;
}
};

@@ -1341,6 +1345,10 @@ static void ConvertStencilFunc5551(GenericStencilFuncState &state) {
// Otherwise we get 1, which we mostly handle, but won't INVERT correctly.
rewriteOps(GE_STENCILOP_INCR, GE_STENCILOP_INVERT);
}
if (!usesRef && state.testRef == 0xFF) {
// Safe to use REPLACE instead of INCR.
rewriteOps(GE_STENCILOP_INCR, GE_STENCILOP_REPLACE);
}
}

void ConvertStencilFuncState(GenericStencilFuncState &state) {
@@ -1,3 +1,4 @@
#include <algorithm>
#include "Common/MemoryUtil.h"
#include "Core/Reporting.h"
#include "GLQueueRunner.h"
@@ -1318,25 +1319,51 @@ void GLQueueRunner::PerformReadback(const GLRStep &pass) {
void GLQueueRunner::PerformReadbackImage(const GLRStep &pass) {
GLRTexture *tex = pass.readback_image.texture;

glBindTexture(GL_TEXTURE_2D, tex->texture);
#ifndef USING_GLES2
GLRect2D rect = pass.readback_image.srcRect;

CHECK_GL_ERROR_IF_DEBUG();
if (gl_extensions.VersionGEThan(4, 5)) {
int size = 4 * rect.w * rect.h;
if (size > readbackBufferSize_) {
delete[] readbackBuffer_;
readbackBuffer_ = new uint8_t[size];
readbackBufferSize_ = size;
}

#ifndef USING_GLES2
int pixelStride = pass.readback_image.srcRect.w;
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glGetTextureSubImage(tex->texture, pass.readback_image.mipLevel, rect.x, rect.y, 0, rect.w, rect.h, 1, GL_RGBA, GL_UNSIGNED_BYTE, readbackBufferSize_, readbackBuffer_);
} else {
glBindTexture(GL_TEXTURE_2D, tex->texture);

GLRect2D rect = pass.readback_image.srcRect;
CHECK_GL_ERROR_IF_DEBUG();

int size = 4 * rect.w * rect.h;
if (size > readbackBufferSize_) {
delete[] readbackBuffer_;
readbackBuffer_ = new uint8_t[size];
readbackBufferSize_ = size;
}
GLint w, h;
// This is only used for debugging (currently), and GL doesn't support a subrectangle.
glGetTexLevelParameteriv(GL_TEXTURE_2D, pass.readback_image.mipLevel, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, pass.readback_image.mipLevel, GL_TEXTURE_HEIGHT, &h);

int size = 4 * std::max((int)w, rect.x + rect.w) * std::max((int)h, rect.h);
if (size > readbackBufferSize_) {
delete[] readbackBuffer_;
readbackBuffer_ = new uint8_t[size];
readbackBufferSize_ = size;
}

glPixelStorei(GL_PACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ROW_LENGTH, rect.x + rect.w);
glGetTexImage(GL_TEXTURE_2D, pass.readback_image.mipLevel, GL_RGBA, GL_UNSIGNED_BYTE, readbackBuffer_);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);

glPixelStorei(GL_PACK_ALIGNMENT, 4);
glGetTexImage(GL_TEXTURE_2D, pass.readback_image.mipLevel, GL_RGBA, GL_UNSIGNED_BYTE, readbackBuffer_);
if (rect.x != 0 || rect.y != 0) {
int dstStride = 4 * rect.w;
int srcStride = 4 * (rect.x + rect.w);
int xoff = 4 * rect.x;
int yoff = rect.y * srcStride;
for (int y = 0; y < rect.h; ++y) {
memmove(readbackBuffer_ + h * dstStride, readbackBuffer_ + yoff + h * srcStride + xoff, dstStride);
}
}
}
#endif

CHECK_GL_ERROR_IF_DEBUG();

0 comments on commit 44685a7

Please sign in to comment.
You can’t perform that action at this time.