mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Add qrenderdoc python SWIG bindings, for the stable/clean interface
This commit is contained in:
+25
-13
@@ -128,18 +128,31 @@ else()
|
||||
"DEFINES+=PYSIDE2_ENABLED=0\n")
|
||||
endif()
|
||||
|
||||
# generate the SWIG interface file
|
||||
add_custom_command(OUTPUT renderdoc_python.cxx renderdoc.py
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/swig -v -Wextra -Werror -O -c++ -python -modern -modernargs -enumclass -fastunpack -py3 -builtin -I${CMAKE_SOURCE_DIR}/renderdoc/api/replay -outdir ${CMAKE_CURRENT_BINARY_DIR} -o ${CMAKE_CURRENT_BINARY_DIR}/renderdoc_python.cxx ${CMAKE_CURRENT_SOURCE_DIR}/Code/pyrenderdoc/renderdoc.i
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Code/pyrenderdoc/renderdoc.i
|
||||
DEPENDS custom_swig
|
||||
DEPENDS renderdoc)
|
||||
# generate the SWIG interface files
|
||||
set(swig_interfaces
|
||||
Code/pyrenderdoc/renderdoc.i
|
||||
Code/pyrenderdoc/qrenderdoc.i)
|
||||
|
||||
add_custom_command(OUTPUT renderdoc.py.c
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/include-bin renderdoc.py renderdoc.py.c
|
||||
DEPENDS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/include-bin
|
||||
DEPENDS renderdoc_python.cxx)
|
||||
set(swig_output)
|
||||
|
||||
foreach(in ${swig_interfaces})
|
||||
get_filename_component(swig_file ${in} NAME_WE)
|
||||
|
||||
add_custom_command(OUTPUT ${swig_file}_python.cxx ${swig_file}.py
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/swig -v -Wextra -Werror -O -c++ -python -modern -modernargs -enumclass -fastunpack -py3 -builtin -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/renderdoc/api/replay -outdir ${CMAKE_CURRENT_BINARY_DIR} -o ${CMAKE_CURRENT_BINARY_DIR}/${swig_file}_python.cxx ${CMAKE_CURRENT_SOURCE_DIR}/${in}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${in}
|
||||
DEPENDS custom_swig
|
||||
DEPENDS renderdoc)
|
||||
|
||||
add_custom_command(OUTPUT ${swig_file}.py.c
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/include-bin ${swig_file}.py ${swig_file}.py.c
|
||||
DEPENDS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/include-bin
|
||||
DEPENDS ${swig_file}_python.cxx)
|
||||
|
||||
list(APPEND swig_output ${swig_file}_python.cxx)
|
||||
list(APPEND swig_output ${swig_file}.py.c)
|
||||
endforeach()
|
||||
|
||||
# The case here is deliberately not matching the executable name
|
||||
# This means the custom command doesn't create this output file,
|
||||
@@ -149,8 +162,7 @@ add_custom_command(OUTPUT QRenderDoc
|
||||
COMMAND qmake "CMAKE_DIR=${CMAKE_BINARY_DIR}" ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND $(MAKE)
|
||||
DEPENDS RenderDoc.icns
|
||||
DEPENDS renderdoc_python.cxx
|
||||
DEPENDS renderdoc.py.c)
|
||||
DEPENDS ${swig_output})
|
||||
add_custom_target(build-qrenderdoc ALL DEPENDS QRenderDoc DEPENDS renderdoc)
|
||||
|
||||
install (PROGRAMS ${CMAKE_BINARY_DIR}/bin/qrenderdoc DESTINATION bin)
|
||||
|
||||
@@ -49,6 +49,8 @@ PyTypeObject **SbkPySide2_QtWidgetsTypes = NULL;
|
||||
// defined in SWIG-generated renderdoc_python.cpp
|
||||
extern "C" PyObject *PyInit__renderdoc(void);
|
||||
extern "C" PyObject *PassObjectToPython(const char *type, void *obj);
|
||||
// this one is in qrenderdoc_python.cpp
|
||||
extern "C" PyObject *PyInit__qrenderdoc(void);
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
@@ -56,9 +58,9 @@ extern "C" PyObject *PassObjectToPython(const char *type, void *obj);
|
||||
#include <windows.h>
|
||||
#include "Resources/resource.h"
|
||||
|
||||
QByteArray GetWrapperModule()
|
||||
QByteArray GetResourceContents(int resource)
|
||||
{
|
||||
HRSRC res = FindResource(NULL, MAKEINTRESOURCE(renderdoc_py_module), MAKEINTRESOURCE(TYPE_EMBED));
|
||||
HRSRC res = FindResource(NULL, MAKEINTRESOURCE(resource), MAKEINTRESOURCE(TYPE_EMBED));
|
||||
HGLOBAL data = LoadResource(NULL, res);
|
||||
|
||||
if(!data)
|
||||
@@ -70,16 +72,17 @@ QByteArray GetWrapperModule()
|
||||
return QByteArray(resData, (int)resSize);
|
||||
}
|
||||
|
||||
#define GetWrapperModule(name) GetResourceContents(name##_py_module)
|
||||
|
||||
#else
|
||||
|
||||
// Otherwise it's compiled in via include-bin which converts to a .c with extern array
|
||||
extern unsigned char renderdoc_py[];
|
||||
extern unsigned int renderdoc_py_len;
|
||||
extern unsigned char qrenderdoc_py[];
|
||||
extern unsigned int qrenderdoc_py_len;
|
||||
|
||||
QByteArray GetWrapperModule()
|
||||
{
|
||||
return QByteArray((const char *)renderdoc_py, (int)renderdoc_py_len);
|
||||
}
|
||||
#define GetWrapperModule(name) QByteArray((const char *)name##_py, (int)name##_py_len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -198,6 +201,7 @@ void PythonContext::GlobalInit()
|
||||
}
|
||||
|
||||
PyImport_AppendInittab("_renderdoc", &PyInit__renderdoc);
|
||||
PyImport_AppendInittab("_qrenderdoc", &PyInit__qrenderdoc);
|
||||
|
||||
Py_SetProgramName(program_name);
|
||||
|
||||
@@ -205,17 +209,26 @@ void PythonContext::GlobalInit()
|
||||
|
||||
PyEval_InitThreads();
|
||||
|
||||
QByteArray module_src = GetWrapperModule();
|
||||
QByteArray renderdoc_py_src = GetWrapperModule(renderdoc);
|
||||
|
||||
if(module_src.isEmpty())
|
||||
if(renderdoc_py_src.isEmpty())
|
||||
{
|
||||
qCritical() << "renderdoc.py wrapper is corrupt/empty. Check build configuration to ensure "
|
||||
"SWIG compiled properly with python support.";
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray qrenderdoc_py_src = GetWrapperModule(qrenderdoc);
|
||||
|
||||
if(qrenderdoc_py_src.isEmpty())
|
||||
{
|
||||
qCritical() << "qrenderdoc.py wrapper is corrupt/empty. Check build configuration to ensure "
|
||||
"SWIG compiled properly with python support.";
|
||||
return;
|
||||
}
|
||||
|
||||
PyObject *renderdoc_py_compiled =
|
||||
Py_CompileString(module_src.data(), "renderdoc.py", Py_file_input);
|
||||
Py_CompileString(renderdoc_py_src.data(), "renderdoc.py", Py_file_input);
|
||||
|
||||
if(!renderdoc_py_compiled)
|
||||
{
|
||||
@@ -223,6 +236,16 @@ void PythonContext::GlobalInit()
|
||||
return;
|
||||
}
|
||||
|
||||
PyObject *qrenderdoc_py_compiled =
|
||||
Py_CompileString(qrenderdoc_py_src.data(), "qrenderdoc.py", Py_file_input);
|
||||
|
||||
if(!qrenderdoc_py_compiled)
|
||||
{
|
||||
Py_DecRef(renderdoc_py_compiled);
|
||||
qCritical() << "Failed to compile qrenderdoc.py wrapper, python will not be available";
|
||||
return;
|
||||
}
|
||||
|
||||
OutputRedirectorType.tp_name = "renderdoc_output_redirector";
|
||||
OutputRedirectorType.tp_basicsize = sizeof(OutputRedirector);
|
||||
OutputRedirectorType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE;
|
||||
@@ -238,10 +261,13 @@ void PythonContext::GlobalInit()
|
||||
PyObject *main_module = PyImport_AddModule("__main__");
|
||||
|
||||
PyObject *rdoc_module = PyImport_ExecCodeModule("renderdoc", renderdoc_py_compiled);
|
||||
PyObject *qrdoc_module = PyImport_ExecCodeModule("qrenderdoc", qrenderdoc_py_compiled);
|
||||
|
||||
Py_XDECREF(renderdoc_py_compiled);
|
||||
Py_XDECREF(qrenderdoc_py_compiled);
|
||||
|
||||
PyModule_AddObject(main_module, "renderdoc", rdoc_module);
|
||||
PyModule_AddObject(main_module, "qrenderdoc", qrdoc_module);
|
||||
|
||||
main_dict = PyModule_GetDict(main_module);
|
||||
|
||||
@@ -480,6 +506,7 @@ void PythonContext::setGlobal(const char *varName, const char *typeName, void *o
|
||||
|
||||
PyGILState_STATE gil = PyGILState_Ensure();
|
||||
|
||||
// we don't need separate functions for each module, as they share type info
|
||||
PyObject *obj = PassObjectToPython(typeName, object);
|
||||
|
||||
int ret = -1;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
%module(docstring="This is the API to QRenderDoc's high-level UI panels and functionality.") qrenderdoc
|
||||
|
||||
%feature("autodoc", "0");
|
||||
|
||||
// use documentation for docstrings
|
||||
#define DOCUMENT(text) %feature("docstring") text
|
||||
|
||||
// import the renderdoc interface that we depend on
|
||||
%import "renderdoc.i"
|
||||
|
||||
SIMPLE_TYPEMAPS(QString)
|
||||
SIMPLE_TYPEMAPS(QDateTime)
|
||||
|
||||
CONTAINER_TYPEMAPS(QList &)
|
||||
CONTAINER_TYPEMAPS(QList *)
|
||||
CONTAINER_TYPEMAPS(QList)
|
||||
CONTAINER_TYPEMAPS(QStringList &)
|
||||
CONTAINER_TYPEMAPS(QStringList *)
|
||||
CONTAINER_TYPEMAPS(QStringList)
|
||||
CONTAINER_TYPEMAPS(QVector &)
|
||||
CONTAINER_TYPEMAPS(QVector *)
|
||||
CONTAINER_TYPEMAPS(QVector)
|
||||
CONTAINER_TYPEMAPS(QMap &)
|
||||
CONTAINER_TYPEMAPS(QMap *)
|
||||
CONTAINER_TYPEMAPS(QMap)
|
||||
|
||||
// ignore these functions as we don't map QVariantMap to/from python
|
||||
%ignore EnvironmentModification::toJSON;
|
||||
%ignore EnvironmentModification::fromJSON;
|
||||
|
||||
// rename the interfaces to remove the I prefix
|
||||
%rename("%(regex:/^I([A-Z].*)/\\1/)s", %$isclass) "";
|
||||
|
||||
%{
|
||||
#define ENABLE_QT_CONVERT
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QTimeZone>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
|
||||
#include "datetime.h"
|
||||
|
||||
#include "Code/Interface/QRDInterface.h"
|
||||
%}
|
||||
|
||||
%include <stdint.i>
|
||||
|
||||
%include "Code/Interface/QRDInterface.h"
|
||||
%include "Code/Interface/CommonPipelineState.h"
|
||||
%include "Code/Interface/PersistantConfig.h"
|
||||
%include "Code/Interface/RemoteHost.h"
|
||||
|
||||
%init %{
|
||||
PyDateTime_IMPORT;
|
||||
%}
|
||||
@@ -101,6 +101,7 @@ END
|
||||
|
||||
// embed the renderdoc.py generated by SWIG
|
||||
renderdoc_py_module TYPE_EMBED RENDERDOC_PY_PATH
|
||||
qrenderdoc_py_module TYPE_EMBED QRENDERDOC_PY_PATH
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#define TYPE_EMBED 256
|
||||
#define renderdoc_py_module 101
|
||||
#define qrenderdoc_py_module 102
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
||||
@@ -52,16 +52,18 @@ win32 {
|
||||
swig.name = SWIG ${QMAKE_FILE_IN}
|
||||
swig.input = SWIGSOURCES
|
||||
swig.output = ${QMAKE_FILE_BASE}_python.cxx
|
||||
swig.commands = $$_PRO_FILE_PWD_/3rdparty/swig/swig.exe -v -Wextra -Werror -O -c++ -python -modern -modernargs -enumclass -fastunpack -py3 -builtin -I$$_PRO_FILE_PWD_/../renderdoc/api/replay -outdir . -o ${QMAKE_FILE_BASE}_python.cxx ${QMAKE_FILE_IN}
|
||||
swig.commands = $$_PRO_FILE_PWD_/3rdparty/swig/swig.exe -v -Wextra -Werror -O -c++ -python -modern -modernargs -enumclass -fastunpack -py3 -builtin -I$$_PRO_FILE_PWD_ -I$$_PRO_FILE_PWD_/../renderdoc/api/replay -outdir . -o ${QMAKE_FILE_BASE}_python.cxx ${QMAKE_FILE_IN}
|
||||
swig.CONFIG += target_predeps
|
||||
swig.variable_out = GENERATED_SOURCES
|
||||
silent:swig.commands = @echo SWIG ${QMAKE_FILE_IN} && $$swig.commands
|
||||
QMAKE_EXTRA_COMPILERS += swig
|
||||
|
||||
SWIGSOURCES += Code/pyrenderdoc/renderdoc.i
|
||||
SWIGSOURCES += Code/pyrenderdoc/qrenderdoc.i
|
||||
|
||||
# Embed renderdoc.py
|
||||
# Embed renderdoc.py and qrenderdoc.py
|
||||
RC_DEFINES = RENDERDOC_PY_PATH=renderdoc.py
|
||||
RC_DEFINES += QRENDERDOC_PY_PATH=qrenderdoc.py
|
||||
|
||||
# Include and link against python
|
||||
INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/python/include
|
||||
@@ -112,6 +114,8 @@ win32 {
|
||||
# Add the SWIG files that were generated in cmake
|
||||
SOURCES += $$CMAKE_DIR/qrenderdoc/renderdoc_python.cxx
|
||||
SOURCES += $$CMAKE_DIR/qrenderdoc/renderdoc.py.c
|
||||
SOURCES += $$CMAKE_DIR/qrenderdoc/qrenderdoc_python.cxx
|
||||
SOURCES += $$CMAKE_DIR/qrenderdoc/qrenderdoc.py.c
|
||||
|
||||
CONFIG += warn_off
|
||||
CONFIG += c++14
|
||||
|
||||
@@ -689,6 +689,9 @@
|
||||
<ClCompile Include="$(IntDir)generated\renderdoc_python.cxx">
|
||||
<DisableSpecificWarnings>4127;4456;4459;4701;4244;4706;4101;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)generated\qrenderdoc_python.cxx">
|
||||
<DisableSpecificWarnings>4127;4456;4459;4701;4244;4706;4101;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Widgets\BufferFormatSpecifier.cpp" />
|
||||
<ClCompile Include="Widgets\FindReplace.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDListWidget.cpp" />
|
||||
@@ -1178,6 +1181,14 @@
|
||||
<Outputs>$(IntDir)generated\%(Filename).py;$(IntDir)generated\%(Filename)_python.cxx;%(Outputs)</Outputs>
|
||||
<LinkObjects>false</LinkObjects>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Code\pyrenderdoc\qrenderdoc.i">
|
||||
<FileType>Document</FileType>
|
||||
<AdditionalInputs>%(Fullpath);Code\Interface\QRDInterface.h;Code\Interface\CommonPipelineState.h;Code\Interface\PersistantConfig.h;Code\Interface\RemoteHost.h;$(IntDir)generated\renderdoc.py;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command>$(ProjectDir)3rdparty\swig\swig.exe -v -Wextra -Werror -O -c++ -python -modern -modernargs -enumclass -fastunpack -py3 -builtin -I$(SolutionDir)renderdoc\api\replay -I$(ProjectDir) -outdir $(IntDir)generated -o $(IntDir)generated\%(Filename)_python.cxx %(FullPath)</Command>
|
||||
<Message>Compiling SWIG interface</Message>
|
||||
<Outputs>$(IntDir)generated\%(Filename).py;$(IntDir)generated\%(Filename)_python.cxx;%(Outputs)</Outputs>
|
||||
<LinkObjects>false</LinkObjects>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Widgets\BufferFormatSpecifier.ui">
|
||||
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command>$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe %(Fullpath) -o $(IntDir)generated\ui_%(Filename).h</Command>
|
||||
@@ -1543,7 +1554,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Resources\qrenderdoc.rc">
|
||||
<PreprocessorDefinitions>RENDERDOC_PY_PATH=$(IntDir)\generated\renderdoc.py;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>RENDERDOC_PY_PATH=$(IntDir)\generated\renderdoc.py;QRENDERDOC_PY_PATH=$(IntDir)\generated\qrenderdoc.py;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -558,6 +558,9 @@
|
||||
<ClCompile Include="Code\pyrenderdoc\PythonContext.cpp">
|
||||
<Filter>Code\pyrenderdoc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)generated\qrenderdoc_python.cxx">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)generated\moc_PythonContext.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -1316,5 +1319,8 @@
|
||||
<CustomBuild Include="Code\pyrenderdoc\PythonContext.h">
|
||||
<Filter>Code\pyrenderdoc</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Code\pyrenderdoc\qrenderdoc.i">
|
||||
<Filter>Code\pyrenderdoc</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user