Capture/Replay: Update CopyImageSubData params
The parameters to glCopyImageSubData are flexible and
can take a TextureID or a RenderbufferID as a GLuint.
Our replay needs to remap those values, so we'll convert the GLuint
based on the target. This leads to a change like the following.
Before:
glCopyImageSubData(138, 0x0DE1, 0, 0, 0, 0,
642, 0x0DE1, 1, 0, 0, 0,
256, 256, 1);
After:
glCopyImageSubData(gTextureMap[138], 0x0DE1, 0, 0, 0, 0,
gTextureMap[642], 0x0DE1, 1, 0, 0, 0,
256, 256, 1);
Test: PUBG Mobile MEC
Bug: angleproject:6087
Bug: angleproject:6104
Change-Id: I5cd422e41ffbb4f08c8909e520bdce63e3008c5a
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2981464
Commit-Queue: Cody Northrop <cnorthrop@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Tim Van Patten <timvp@google.com>
diff --git a/src/libANGLE/capture/FrameCapture.cpp b/src/libANGLE/capture/FrameCapture.cpp
index f443007..2a5c66d 100644
--- a/src/libANGLE/capture/FrameCapture.cpp
+++ b/src/libANGLE/capture/FrameCapture.cpp
@@ -3710,13 +3710,25 @@
// cached texture entry for use during mid-execution capture, rather than reading it back with
// ANGLE_get_image.
- GLuint srcName = call.params.getParam("srcName", ParamType::TGLuint, 0).value.GLuintVal;
+ GLenum srcTarget = call.params.getParam("srcTarget", ParamType::TGLenum, 1).value.GLenumVal;
+ GLenum dstTarget = call.params.getParam("dstTarget", ParamType::TGLenum, 7).value.GLenumVal;
+
+ // TODO(anglebug.com/6104): Type of incoming ID varies based on target type, but we're only
+ // handling textures for now. If either of these asserts fire, then we need to add renderbuffer
+ // support.
+ ASSERT(srcTarget == GL_TEXTURE_2D || srcTarget == GL_TEXTURE_2D_ARRAY ||
+ srcTarget == GL_TEXTURE_3D || srcTarget == GL_TEXTURE_CUBE_MAP);
+ ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY ||
+ dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP);
+
+ gl::TextureID srcName =
+ call.params.getParam("srcName", ParamType::TTextureID, 0).value.TextureIDVal;
GLint srcLevel = call.params.getParam("srcLevel", ParamType::TGLint, 2).value.GLintVal;
- GLuint dstName = call.params.getParam("dstName", ParamType::TGLuint, 6).value.GLuintVal;
+ gl::TextureID dstName =
+ call.params.getParam("dstName", ParamType::TTextureID, 6).value.TextureIDVal;
GLint dstLevel = call.params.getParam("dstLevel", ParamType::TGLint, 8).value.GLintVal;
// Look up the texture type
- GLenum dstTarget = call.params.getParam("dstTarget", ParamType::TGLenum, 7).value.GLenumVal;
gl::TextureTarget dstTargetPacked = gl::PackParam<gl::TextureTarget>(dstTarget);
gl::TextureType dstTextureType = gl::TextureTargetToType(dstTargetPacked);
@@ -3729,7 +3741,7 @@
if (dstFormat.compressed)
{
context->getShareGroup()->getFrameCaptureShared()->copyCachedTextureLevel(
- context, {srcName}, srcLevel, {dstName}, dstLevel, call);
+ context, srcName, srcLevel, dstName, dstLevel, call);
}
}
@@ -3948,6 +3960,69 @@
}
}
+void FrameCapture::updateCopyImageSubData(CallCapture &call)
+{
+ // This call modifies srcName and dstName to no longer be object IDs (GLuint), but actual
+ // packed types that can remapped using gTextureMap and gRenderbufferMap
+
+ GLint srcName = call.params.getParam("srcName", ParamType::TGLuint, 0).value.GLuintVal;
+ GLenum srcTarget = call.params.getParam("srcTarget", ParamType::TGLenum, 1).value.GLenumVal;
+ switch (srcTarget)
+ {
+ case GL_RENDERBUFFER:
+ {
+ // Convert the GLuint to RenderbufferID
+ gl::RenderbufferID srcRenderbufferID = {static_cast<GLuint>(srcName)};
+ call.params.setValueParamAtIndex("srcName", ParamType::TRenderbufferID,
+ srcRenderbufferID, 0);
+ break;
+ }
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_CUBE_MAP:
+ {
+ // Convert the GLuint to TextureID
+ gl::TextureID srcTextureID = {static_cast<GLuint>(srcName)};
+ call.params.setValueParamAtIndex("srcName", ParamType::TTextureID, srcTextureID, 0);
+ break;
+ }
+ default:
+ ERR() << "Unhandled srcTarget = " << srcTarget;
+ UNREACHABLE();
+ break;
+ }
+
+ // Change dstName to the appropriate type based on dstTarget
+ GLint dstName = call.params.getParam("dstName", ParamType::TGLuint, 6).value.GLuintVal;
+ GLenum dstTarget = call.params.getParam("dstTarget", ParamType::TGLenum, 7).value.GLenumVal;
+ switch (dstTarget)
+ {
+ case GL_RENDERBUFFER:
+ {
+ // Convert the GLuint to RenderbufferID
+ gl::RenderbufferID dstRenderbufferID = {static_cast<GLuint>(dstName)};
+ call.params.setValueParamAtIndex("dstName", ParamType::TRenderbufferID,
+ dstRenderbufferID, 6);
+ break;
+ }
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_CUBE_MAP:
+ {
+ // Convert the GLuint to TextureID
+ gl::TextureID dstTextureID = {static_cast<GLuint>(dstName)};
+ call.params.setValueParamAtIndex("dstName", ParamType::TTextureID, dstTextureID, 6);
+ break;
+ }
+ default:
+ ERR() << "Unhandled dstTarget = " << dstTarget;
+ UNREACHABLE();
+ break;
+ }
+}
+
void FrameCapture::maybeOverrideEntryPoint(const gl::Context *context, CallCapture &call)
{
switch (call.entryPoint)
@@ -3966,6 +4041,14 @@
UNIMPLEMENTED();
break;
}
+ case EntryPoint::GLCopyImageSubData:
+ case EntryPoint::GLCopyImageSubDataEXT:
+ case EntryPoint::GLCopyImageSubDataOES:
+ {
+ // We must look at the src and dst target types to determine which remap table to use
+ updateCopyImageSubData(call);
+ break;
+ }
default:
break;
}
diff --git a/src/libANGLE/capture/FrameCapture.h b/src/libANGLE/capture/FrameCapture.h
index 0967de2..30161ad 100644
--- a/src/libANGLE/capture/FrameCapture.h
+++ b/src/libANGLE/capture/FrameCapture.h
@@ -55,6 +55,8 @@
template <typename T>
void addValueParam(const char *paramName, ParamType paramType, T paramValue);
template <typename T>
+ void setValueParamAtIndex(const char *paramName, ParamType paramType, T paramValue, int index);
+ template <typename T>
void addEnumParam(const char *paramName,
gl::GLenumGroup enumGroup,
ParamType paramType,
@@ -390,6 +392,7 @@
void maybeCaptureDrawElementsClientData(const gl::Context *context,
CallCapture &call,
size_t instanceCount);
+ void updateCopyImageSubData(CallCapture &call);
static void ReplayCall(gl::Context *context,
ReplayContext *replayContext,
@@ -504,6 +507,19 @@
}
template <typename T>
+void ParamBuffer::setValueParamAtIndex(const char *paramName,
+ ParamType paramType,
+ T paramValue,
+ int index)
+{
+ ASSERT(mParamCaptures.size() > static_cast<size_t>(index));
+
+ ParamCapture capture(paramName, paramType);
+ InitParamValue(paramType, paramValue, &capture.value);
+ mParamCaptures[index] = std::move(capture);
+}
+
+template <typename T>
void ParamBuffer::addEnumParam(const char *paramName,
gl::GLenumGroup enumGroup,
ParamType paramType,