| // |
| // Copyright 2022 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // frame_capture_utils.h: |
| // ANGLE Frame capture common classes. |
| // |
| |
| #ifndef COMMON_FRAME_CAPTURE_UTILS_H_ |
| #define COMMON_FRAME_CAPTURE_UTILS_H_ |
| |
| #include "common/frame_capture_utils_autogen.h" |
| #include "common/gl_enum_utils_autogen.h" |
| |
| namespace angle |
| { |
| namespace |
| { |
| template <typename ParamValueType> |
| struct ParamValueTrait |
| { |
| static_assert(sizeof(ParamValueType) == 0, "invalid ParamValueType"); |
| }; |
| |
| template <> |
| struct ParamValueTrait<gl::FramebufferID> |
| { |
| static constexpr const char *name = "framebufferPacked"; |
| static const ParamType typeID = ParamType::TFramebufferID; |
| }; |
| |
| template <> |
| struct ParamValueTrait<gl::BufferID> |
| { |
| static constexpr const char *name = "bufferPacked"; |
| static const ParamType typeID = ParamType::TBufferID; |
| }; |
| |
| template <> |
| struct ParamValueTrait<gl::RenderbufferID> |
| { |
| static constexpr const char *name = "renderbufferPacked"; |
| static const ParamType typeID = ParamType::TRenderbufferID; |
| }; |
| |
| template <> |
| struct ParamValueTrait<gl::TextureID> |
| { |
| static constexpr const char *name = "texturePacked"; |
| static const ParamType typeID = ParamType::TTextureID; |
| }; |
| |
| template <> |
| struct ParamValueTrait<gl::ShaderProgramID> |
| { |
| static constexpr const char *name = "programPacked"; |
| static const ParamType typeID = ParamType::TShaderProgramID; |
| }; |
| } // namespace |
| |
| using ParamData = std::vector<std::vector<uint8_t>>; |
| struct ParamCapture : angle::NonCopyable |
| { |
| ParamCapture(); |
| ParamCapture(const char *nameIn, ParamType typeIn); |
| ~ParamCapture(); |
| |
| ParamCapture(ParamCapture &&other); |
| ParamCapture &operator=(ParamCapture &&other); |
| |
| std::string name; |
| ParamType type; |
| ParamValue value; |
| gl::GLESEnum enumGroup; // only used for param type GLenum, GLboolean and GLbitfield |
| gl::BigGLEnum bigGLEnum; // only used for param type GLenum, GLboolean and GLbitfield |
| ParamData data; |
| int dataNElements = 0; |
| int arrayClientPointerIndex = -1; |
| size_t readBufferSizeBytes = 0; |
| uint32_t uniqueID = 0; |
| static uint32_t nextID; |
| }; |
| |
| using Captures = std::vector<ParamCapture>; |
| |
| class ParamBuffer final : angle::NonCopyable |
| { |
| public: |
| ParamBuffer(); |
| ~ParamBuffer(); |
| |
| ParamBuffer(ParamBuffer &&other); |
| ParamBuffer &operator=(ParamBuffer &&other); |
| |
| 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::GLESEnum enumGroup, |
| ParamType paramType, |
| T paramValue); |
| template <typename T> |
| void addEnumParam(const char *paramName, |
| gl::BigGLEnum enumGroup, |
| ParamType paramType, |
| T paramValue); |
| |
| template <typename T> |
| void addUnnamedParam(ParamType paramType, T paramValue); |
| |
| ParamCapture &getParam(const char *paramName, ParamType paramType, int index); |
| const ParamCapture &getParam(const char *paramName, ParamType paramType, int index) const; |
| ParamCapture &getParamFlexName(const char *paramName1, |
| const char *paramName2, |
| ParamType paramType, |
| int index); |
| const ParamCapture &getParamFlexName(const char *paramName1, |
| const char *paramName2, |
| ParamType paramType, |
| int index) const; |
| const ParamCapture &getReturnValue() const { return mReturnValueCapture; } |
| |
| void addParam(ParamCapture &¶m); |
| void addReturnValue(ParamCapture &&returnValue); |
| bool hasClientArrayData() const { return mClientArrayDataParam != -1; } |
| ParamCapture &getClientArrayPointerParameter(); |
| size_t getReadBufferSize() const { return mReadBufferSize; } |
| |
| bool empty() const { return mParamCaptures.empty(); } |
| const std::vector<ParamCapture> &getParamCaptures() const { return mParamCaptures; } |
| |
| const char *getNextParamName(); |
| |
| private: |
| std::vector<ParamCapture> mParamCaptures; |
| ParamCapture mReturnValueCapture; |
| int mClientArrayDataParam = -1; |
| size_t mReadBufferSize = 0; |
| }; |
| |
| struct CallCapture |
| { |
| CallCapture(EntryPoint entryPointIn, ParamBuffer &¶msIn); |
| CallCapture(const std::string &customFunctionNameIn, ParamBuffer &¶msIn); |
| ~CallCapture(); |
| |
| CallCapture(CallCapture &&other); |
| CallCapture &operator=(CallCapture &&other); |
| |
| const char *name() const; |
| |
| EntryPoint entryPoint; |
| std::string customFunctionName; |
| ParamBuffer params; |
| bool isActive = true; |
| gl::ContextID contextID; |
| bool isSyncPoint = false; |
| }; |
| |
| template <typename T> |
| void ParamBuffer::addValueParam(const char *paramName, ParamType paramType, T paramValue) |
| { |
| ParamCapture capture(paramName, paramType); |
| InitParamValue(paramType, paramValue, &capture.value); |
| mParamCaptures.emplace_back(std::move(capture)); |
| } |
| |
| 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::GLESEnum enumGroup, |
| ParamType paramType, |
| T paramValue) |
| { |
| ParamCapture capture(paramName, paramType); |
| InitParamValue(paramType, paramValue, &capture.value); |
| capture.enumGroup = enumGroup; |
| mParamCaptures.emplace_back(std::move(capture)); |
| } |
| |
| template <typename T> |
| void ParamBuffer::addEnumParam(const char *paramName, |
| gl::BigGLEnum enumGroup, |
| ParamType paramType, |
| T paramValue) |
| { |
| ParamCapture capture(paramName, paramType); |
| InitParamValue(paramType, paramValue, &capture.value); |
| capture.bigGLEnum = enumGroup; |
| mParamCaptures.emplace_back(std::move(capture)); |
| } |
| |
| template <typename T> |
| void ParamBuffer::addUnnamedParam(ParamType paramType, T paramValue) |
| { |
| addValueParam(getNextParamName(), paramType, paramValue); |
| } |
| |
| template <ParamType ParamT, typename T> |
| void WriteParamValueReplay(std::ostream &os, const CallCapture &call, T value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLboolean>(std::ostream &os, |
| const CallCapture &call, |
| GLboolean value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLbooleanPointer>(std::ostream &os, |
| const CallCapture &call, |
| GLboolean *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TvoidConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| const void *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TvoidPointer>(std::ostream &os, |
| const CallCapture &call, |
| void *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLfloatConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| const GLfloat *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLintConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| const GLint *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLsizeiPointer>(std::ostream &os, |
| const CallCapture &call, |
| GLsizei *value); |
| template <> |
| void WriteParamValueReplay<ParamType::TGLuintPointer>(std::ostream &os, |
| const CallCapture &call, |
| GLuint *value); |
| template <> |
| void WriteParamValueReplay<ParamType::TGLuintConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| const GLuint *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLDEBUGPROCKHR>(std::ostream &os, |
| const CallCapture &call, |
| GLDEBUGPROCKHR value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLDEBUGPROC>(std::ostream &os, |
| const CallCapture &call, |
| GLDEBUGPROC value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TBufferID>(std::ostream &os, |
| const CallCapture &call, |
| gl::BufferID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TFenceNVID>(std::ostream &os, |
| const CallCapture &call, |
| gl::FenceNVID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TFramebufferID>(std::ostream &os, |
| const CallCapture &call, |
| gl::FramebufferID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TMemoryObjectID>(std::ostream &os, |
| const CallCapture &call, |
| gl::MemoryObjectID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TProgramPipelineID>(std::ostream &os, |
| const CallCapture &call, |
| gl::ProgramPipelineID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TQueryID>(std::ostream &os, |
| const CallCapture &call, |
| gl::QueryID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TRenderbufferID>(std::ostream &os, |
| const CallCapture &call, |
| gl::RenderbufferID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TSamplerID>(std::ostream &os, |
| const CallCapture &call, |
| gl::SamplerID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TSemaphoreID>(std::ostream &os, |
| const CallCapture &call, |
| gl::SemaphoreID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TShaderProgramID>(std::ostream &os, |
| const CallCapture &call, |
| gl::ShaderProgramID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TTextureID>(std::ostream &os, |
| const CallCapture &call, |
| gl::TextureID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TTransformFeedbackID>(std::ostream &os, |
| const CallCapture &call, |
| gl::TransformFeedbackID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TVertexArrayID>(std::ostream &os, |
| const CallCapture &call, |
| gl::VertexArrayID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TUniformLocation>(std::ostream &os, |
| const CallCapture &call, |
| gl::UniformLocation value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TUniformBlockIndex>(std::ostream &os, |
| const CallCapture &call, |
| gl::UniformBlockIndex value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TSyncID>(std::ostream &os, |
| const CallCapture &call, |
| gl::SyncID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLubyte>(std::ostream &os, |
| const CallCapture &call, |
| GLubyte value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TContextID>(std::ostream &os, |
| const CallCapture &call, |
| gl::ContextID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tegl_DisplayPointer>(std::ostream &os, |
| const CallCapture &call, |
| egl::Display *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TImageID>(std::ostream &os, |
| const CallCapture &call, |
| egl::ImageID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TSurfaceID>(std::ostream &os, |
| const CallCapture &call, |
| egl::SurfaceID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLDEBUGPROCKHR>(std::ostream &os, |
| const CallCapture &call, |
| EGLDEBUGPROCKHR value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLGetBlobFuncANDROID>(std::ostream &os, |
| const CallCapture &call, |
| EGLGetBlobFuncANDROID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLSetBlobFuncANDROID>(std::ostream &os, |
| const CallCapture &call, |
| EGLSetBlobFuncANDROID value); |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLClientBuffer>(std::ostream &os, |
| const CallCapture &call, |
| EGLClientBuffer value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLAttribPointer>(std::ostream &os, |
| const CallCapture &call, |
| EGLAttrib *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLAttribConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| const EGLAttrib *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLintPointer>(std::ostream &os, |
| const CallCapture &call, |
| EGLint *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLintConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| const EGLint *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tegl_ConfigPointer>(std::ostream &os, |
| const CallCapture &call, |
| egl::Config *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tegl_SyncID>(std::ostream &os, |
| const CallCapture &call, |
| egl::SyncID value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLTime>(std::ostream &os, |
| const CallCapture &call, |
| EGLTime value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TEGLTimeKHR>(std::ostream &os, |
| const CallCapture &call, |
| EGLTimeKHR value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLGETBLOBPROCANGLE>(std::ostream &os, |
| const CallCapture &call, |
| GLGETBLOBPROCANGLE value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TGLSETBLOBPROCANGLE>(std::ostream &os, |
| const CallCapture &call, |
| GLSETBLOBPROCANGLE value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TcharConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| const char *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tsize_tPointer>(std::ostream &os, |
| const CallCapture &call, |
| size_t *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tsize_tConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| size_t const *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TcharConstPointerPointer>(std::ostream &os, |
| const CallCapture &call, |
| const char **value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::TcharUnsignedConstPointerPointer>( |
| std::ostream &os, |
| const CallCapture &call, |
| const unsigned char **value); |
| |
| #ifdef ANGLE_ENABLE_CL |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_platform_idPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_platform_id *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_uintPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_uint *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_device_idPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_device_id *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_context_propertiesConstPointer>( |
| std::ostream &os, |
| const CallCapture &call, |
| cl_context_properties const *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_eventPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_event *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_eventConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_event const *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_device_idConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_device_id const *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_image_formatPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_image_format *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_intPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_int *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_queue_propertiesConstPointer>( |
| std::ostream &os, |
| const CallCapture &call, |
| const cl_queue_properties *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_command_queue_propertiesPointer>( |
| std::ostream &os, |
| const CallCapture &call, |
| const cl_command_queue_properties *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_device_partition_propertyConstPointer>( |
| std::ostream &os, |
| const CallCapture &call, |
| const cl_device_partition_property *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_programConstPointer>(std::ostream &os, |
| const CallCapture &call, |
| const cl_program *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_pipe_propertiesConstPointer>( |
| std::ostream &os, |
| const CallCapture &call, |
| const cl_pipe_properties *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_ulongPointer>(std::ostream &os, |
| const CallCapture &call, |
| cl_ulong *value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_callback_func_type>(std::ostream &os, |
| const CallCapture &call, |
| cl_callback_func_type value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_context_destructor_func_type>( |
| std::ostream &os, |
| const CallCapture &call, |
| cl_context_destructor_func_type value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_context_func_type>(std::ostream &os, |
| const CallCapture &call, |
| cl_context_func_type value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_mem_destructor_func_type>( |
| std::ostream &os, |
| const CallCapture &call, |
| cl_mem_destructor_func_type value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_program_func_type>(std::ostream &os, |
| const CallCapture &call, |
| cl_program_func_type value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_svm_free_callback_func_type>( |
| std::ostream &os, |
| const CallCapture &call, |
| cl_svm_free_callback_func_type value); |
| |
| template <> |
| void WriteParamValueReplay<ParamType::Tcl_void_func_type>(std::ostream &os, |
| const CallCapture &call, |
| cl_void_func_type value); |
| |
| template <ParamType ParamT> |
| void WriteParamValueReplay(std::ostream &os, const CallCapture &call, cl::BitField value) |
| { |
| os << value.get(); |
| } |
| |
| #endif |
| |
| // General fallback for any unspecific type. |
| template <ParamType ParamT, typename T> |
| void WriteParamValueReplay(std::ostream &os, const CallCapture &call, T value) |
| { |
| os << value; |
| } |
| |
| struct FmtPointerIndex |
| { |
| FmtPointerIndex(const void *ptrIn) : ptr(ptrIn) {} |
| const void *ptr; |
| }; |
| |
| inline std::ostream &operator<<(std::ostream &os, const FmtPointerIndex &fmt) |
| { |
| os << reinterpret_cast<uintptr_t>(fmt.ptr) << "ul"; |
| return os; |
| } |
| |
| template <typename ParamValueType> |
| bool FindResourceIDsInCall(const CallCapture &call, std::vector<ParamValueType> &idsOut); |
| } // namespace angle |
| |
| #endif // COMMON_FRAME_CAPTURE_UTILS_H_ |