Today we’re excited to announce the release of a new D3D12 feature: Application Specific Driver State. This feature is intended to be used by capture/replay tools, such as PIX on Windows, to help with issues caused by “app detect” behavior.
Background
D3D12 drivers occasionally have to perform workarounds for bugs in specific applications. For example, this may occur if an older game shipped with a bug that only affects a new generation of GPUs. The driver may be forced to detect when the application is running and then perform an application-specific workaround for the bug. This behavior is often called “app detect”.
This “app detect” behavior causes problems for capture/replay tools like PIX on Windows. For example, if PIX is capturing an application that is subject to “app detect” driver changes, then the application will work at capture time but PIX may hit errors when it tries to replay the captured GPU workload in a separate PIX process.
Application Specific Driver State
This preview adds a new D3D12 functionality that allows capture/replay tools, like PIX, to capture any active application specific workarounds, store them in the capture file, and then tell the driver to set them at replay time.
Sample Code : Capture
#include <wrl/client.h>
using namespace Microsoft::WRL;
// Special GUID that's dedicated to retrieve application specific driver state
static constexpr GUID GUID_MetaCommand_GetApplicationSpecificDriverState =
{ 0xa6b7c5b7, 0x9ec2, 0x4613, { 0xb4, 0x4b, 0x0, 0x21, 0x27, 0xeb, 0xa2, 0x7d } };
// This struct is expected when executing Application Specific Driver State metacommand
// Note: This is subject to change as the feature makes it towards non-preview release
struct ApplicationSpecificDriverStateMetaCommandParameters
{
UINT* pBlobSize;
void* pApplicationSpecificDriverStateBlob;
};
...
ComPtr<ID3D12Device5> device;
ComPtr<ID3DBlob> asdsBlob;
ComPtr<ID3D12GraphicsCommandList> cl;
...
// Query ID3D12DeviceTools1. Succeeds if the runtime supports the feature
ComPtr<ID3D12DeviceTools1> deviceTools1;
if (SUCCEEDED(device->QueryInterface(IID_PPV_ARGS(&deviceTools1))))
{
// Check feature support for Application Specific Driver State
D3D12_FEATURE_DATA_APPLICATION_SPECIFIC_DRIVER_STATE featureDataASDS{};
if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_APPLICATION_SPECIFIC_DRIVER_STATE, &featureDataASDS, sizeof(featureDataASDS))) && featureDataASDS.Supported)
{
// Get application-specific driver state blob
deviceTools1->GetApplicationSpecificDriverState(&asdsBlob);
}
}
else
{ // Runtime does not support the feature
// Use Metacommand to retrieve Application Specific Driver State
ComPtr<ID3D12MetaCommand> metaCommand;
// Check if the device supports GUID_MetaCommand_GetApplicationSpecificDriverState
if (IsMetaCommandAvailable(GUID_MetaCommand_GetApplicationSpecificDriverState, device.Get()))
{
device->CreateMetaCommand(GUID_MetaCommand_GetApplicationSpecificDriverState, 0, nullptr, 0, IID_PPV_ARGS(&metaCommand));
UINT asdsBlobSize = 0u;
ApplicationSpecificDriverStateMetaCommandParameters asdsBlobInfo{ &asdsBlobSize, nullptr };
// Get application specific driver state blob size
// Driver writes actual blob size to pBlobSize if *pBlobSize is smaller than required size
cl->ExecuteMetaCommand(metaCommand.Get(), &asdsBlobInfo, sizeof(asdsBlobInfo));
// Allocate memory for the blob and update pApplicationSpecificDriverStateBlob
...
// ExecuteMetaCommand again, now with >= required size
// Driver writes application specific driver state blob to pApplicationSpecificDriverStateBlob
cl->ExecuteMetaCommand(metaCommand.Get(), &asdsBlobInfo, sizeof(asdsBlobInfo));
}
}
Sample Code : Replay
#include <wrl/client.h>
using namespace Microsoft::WRL;
ComPtr<ID3D12Tools> pD3D12Tools;
D3D12GetDebugInterface(IID_PPV_ARGS(&pD3D12Tools));
// This means that the runtime does not support application specific driver state
ComPtr<ID3D12Tools2> pD3D12Tools2;
if (FAILED(pD3D12Tools->QueryInterface(IID_PPV_ARGS(&pD3D12Tools2))))
{
return;
}
// SetApplicationSpecificDriverState
ThrowFailure(pD3D12Tools2->SetApplicationSpecificDriverState(adapter.Get(), capturedASDSBlob.Get()));
// Create D3D12 Device
...
// Check if the driver supports the feature
D3D12_FEATURE_DATA_APPLICATION_SPECIFIC_DRIVER_STATE featureDataASDS{};
if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_APPLICATION_SPECIFIC_DRIVER_STATE, &featureDataASDS, sizeof(featureDataASDS)))
|| !featureDataASDS.Supported)
{
return;
}
// Status of whether the driver used set app-specific driver state blob
D3D12_APPLICATION_SPECIFIC_DRIVER_BLOB_STATUS setBlobStatus = deviceTools1->GetApplicationSpecificDriverBlobStatus();
...
// If set blob status is IGNORED or UNKNOWN, check if it's due to difference in identifiers
D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS status = device->CheckDriverMatchingIdentifier(D3D12_SERIALIZED_DATA_APPLICATION_SPECIFIC_DRIVER_STATE, pIdentifier);
Words from our Partners:
AMD:
“AMD support for Application Specific Driver State will be available in a developer preview driver in early February. A link to the driver will be posted here when it is available.”
Intel:
“We are excited to be supporting these improvements in an upcoming driver – stay tuned for more details.”
Nvidia:
“NVIDIA will fully support this SDK release, please contact your developer relations representative for specifics.”
Qualcomm:
“Feature support is planned and to be available at a future date”
PIX support
As usual, PIX has day one support for Application Specific Driver State. Please see this blog post for more information.
0 comments
Be the first to start the discussion.