* Note, this API is still in-flux and beta, so there may still be some
more changes before it's 'stable', and even then it will still be
subject to some amount of change.
* This API is then exposed to python via SWIG bindings and hides
internals that don't need to be visible, and means the actual API is
easier to work with.
* We also use this API to reduce inter-dependencies between different
windows that need to interact with each other at a high level.
* The naming is python/standard RenderDoc TitleCase method names, not
Qt style camelCase methods.
# Conflicts:
# qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp
# qrenderdoc/Windows/TextureViewer.cpp
* We need to keep a PythonContext (and its globals Dict) around while
we still have some pending callbacks happening. So now the external
code creates a PythonContext and then releases it when it's done, but
the context will hang around until the global redirector object is
destructed, which is responsible for deleting the context.
* The global redirector is deleted when a refcounting cycle is detected
and the dict is unreachable, which only happens after the context is
released.
* Any time a callback is passed to something and converted to a
std::function we add a reference on the global redirector to keep it
alive. When the callback has finished executing we remove the ref.
* This way, any pending callbacks that have been called but not finished
or converted (queued) and not called yet asynchronously will keep the
context object alive to be able to output, handle exceptions, etc.
* Additionally we need to detect when we're being called asynchronously
and handle exceptions separately instead of trying to propagate up the
call chain, because there might not be any more python code up the
chain (e.g. the render manager calling a python callback).
* Using a separate dict for globals/locals for each interpreter means we
still get separation of variables and no persistence where we don't
want it, but removing sub-interpreters means pyside can work as it
uses the PyGILState_ APIs which do not support sub-interpreters.
* We import everything up front then duplicate the __main__ each time we
create a new context so we keep the __main__ pristine and muck up an
individual copy.
* Because sys is now shared, the output redirectors that overwrite
sys.stdout and sys.stderr have a NULL context, and instead they look
up a specific global which contains the actual context pointer.
* SWIG outputs two files - renderdoc_python.cpp with the main actual
wrapping code, and renderdoc.py a small module that does some
bootstrapping on python side.
* We use a custom version of SWIG that generates strong/typed enums in
python based on enum classes, so in cmake we add this custom swig
fork as an external project and compile it before generating the
wrappers. On windows there's a committed version of the SWIG binary
that gets run directly from the .pro or .vcxproj.
* The renderdoc.py gets embedded as a resource on windows or as a C
generated unsigned char array via include-bin on other platforms, so
that we can insert it into the python context without needing it to
sit around on disk somewhere in sys.path
* Previously the cmake build would put librenderdoc.so in a /bin folder
in the source folder so the qt creator project could link against a
fixed path when just opening the project solo.
* This won't scale though for fetching the SWIG outputs from cmake, and
it's ugly to modify the source folder for out-of-source builds.
* Instead we have cmake generate a qt creator include file with all of
the settings and paths needed, and pass the CMAKE_BINARY_DIR into
qmake when building. This does mean that when opening the project in
qt creator you need to specify CMAKE_DIR=/path/to/build though.
* As a bonus, this means we can let cmake identify where python is and
have qt creator link against it rather than having to hardcode include
paths etc.
* Things like addressing modes, stencil operations, and other things the
UI didn't need to know about previously were only exposed as string
values to be passed through and displayed.
* Now we describe these with enums so the API can be properly
introspected and used by consumers that might want to know the actual
values of these states.
* This goes all the way back to the first iterations where these were
the only structures and 'Fetch' referred to them returning data from
the core code to the UI.
* The functions are still exported and that's all renderdocui cares for.
* The interface is no longer to be used so gets in the way of the
generated SWIG bindings.
* For SWIG bindings we need something that will go type -> string name
so we can look up the SWIG type in a template to convert elements in
arrays.
* An upcoming refactor will contain this kind of typename for proper
reflection, so to minimise code churn and avoid adding multiple new
solutions for the same kind of thing, we borrow the macro name and
implement it for the API structs we need.
* Moving into a namespace makes it easier to give the structs non-clumsy
names while still being unique and not overlapping with the other API
pipeline states.
* SWIG doesn't handle nested structs conversion to python, so we are
going to split out all structs. Mostly this is the case in the
pipeline state structs, but this commit splits out a few in the rest
of the API.
* This gives a little nicer syntax, a bit better type safety, and also
reflects better for SWIG bindings. Overall it's a minor change but
better.
* We don't update the C# UI at all, since it's soon to be removed and
not worth the effort/code churn.
* For now so we're ABI compatible with C#, all enums are uint32_t, but
that is an obvious optimisation in future to reduce struct packing.
* We avoid 'None' as an enum value, because it's a reserved word in
python so will cause problems generating bindings.
Eliminate driver warnings for invalid framebuffer attachments, blends
and image formats (in case of glBindImageTexture). Framebuffer
attachment data query and setter codes are also refactored a bit.