* If the current state of a temporary ImageState is unknown in a renderpass
transition mid-command buffer that means it's a subresource which isn't
touched and we want to skip barriering it. We *don't* want to barrier from
UNDEFINED and discard.
* However if this is a real ImageState which hasn't been initialised, we do want
to do that. So only opt-in to the skipping behaviour in the case we know this
isn't a 'real' ImageState but a temporary tracker.
* The D3D12SDKLayers needs to match the D3D12Core, so we save both when possible
(the SDKLayers dll might not be loaded during capture but it should be next to
the D3D12Core. On replay if we have one we put it next to the D3D12Core we're
using for replay, and if not we forcibly disable debug otherwise we may crash.
Block-compressed textures with dimensions that are not evenly divisible
by the block size are typically padded internally to align with the
block size. load_dds_from_file() was previously corrected to account for
this alignment when calculating the number of rows of blocks to read
from a DDS file, but the fix was not applied to write_dds_to_file(),
resulting in missing rows of texels or loading failures when attempting
to open a DDS file generated by RenderDoc from a texture whose
dimensions are not a multiple of four.
The python brew install does not include universal binaries
Disabling pyrenderdoc on Apple allows for the generation of universal binaries by the Apple CI
* By intercepting D3D12.dll's load of D3D12Core.dll and wrapping the COM
interface it gets back, we can load the D3D12Core.dll that we desired.
* As a default, we load the D3D12Core.dll embedded in the capture. There's also
a config setting to allow the user to override this, though in principle this
shouldn't be needed.
* We only do all this if the SDK version used to capture is higher than that
normally available on the system. So if a new runtime isn't in use, we won't
do any hooking at all.
* This is required for the new heap-indexing bindless because we don't even have
ranges to mark referenced, but for other cases ref-all resources tends to be
more efficient especially when we're going to get to the same place (including
all resources) via a less efficient mechanism.
* Most remote replay links are slow enough that the lag introduced by
synchronously fetching and displaying these thumbnails would be annoying for
simple mouse-over scenarios.
These operations now run on the main thread and not on the Replay thread
* Updating the NSOpenGLContext
* Setting the view property on the NSOpenGLContext
* Getting the window size from the NSView
The specific methods that are run on the main thread are:
* NSOpenGLContext setView
* NSOpenGLContext update
* NSView frame
* NSView convertSizeToBacking
* NSView setWantsBestResolutionOpenGLSurface
These methods are asynchronously dispatched to the main thread using the Apple NSApplication main thread dispatch queue i.e.
dispatch_async(dispatch_get_main_queue(), <method>);
The threading synchronization intent is:
* the Replay does not block waiting for a deferred main thread API to complete
* mutex locks are used to protect containers shared between the main and Replay threads
* the main thread uses a TryLock approach when wanting to acquire the context lock. If the context lock is held by the Replay thread then the main thread reschedules the requested context operation i.e.
if (TryToGetContectLock(context))
{
[context update];
}
else
{
scheduleContextUpdate(context);
}
* When scheduling requests to the main thread the NSOpenGLContext and NSView objects are referred to by an index into an array and not by pointer value.
There are two debugging modes which are disabled by default
* RD_THREAD_RANDOM_SLEEP
* RD_USE_CONTEXT_LOCK_COUNTS
Enabling RD_THREAD_RANDOM_SLEEP performs sleeps of random times on both the Replay and main thread when calling the different context and view methods.
RD_THREAD_RANDOM_SLEEP is useful to expose race conditions.
Enabling RD_USE_CONTEXT_LOCK_COUNTS tracks the lock count on the context objects in the "s_ContextLocksCount" container.
The low-level context locking is handled in NSGL_makeCurrentContext which is called from CGLPlatform::MakeContextCurrent which in turn is called from GLReplay::MakeCurrentReplayContext.
The currently locked context is tracked in TLS storage and the currently locked context is unlocked before locking the new context and then setting the current context TLS value.
* If there would be no tooltip otherwise, it just shows the thumbnail. Otherwise
any tooltip text (like view parameters or image layout) is displayed below the
thumbnail