Allow capturing with DXIL shaders. Closes #1718

This commit is contained in:
baldurk
2020-06-18 17:22:44 +01:00
parent 6783f6a851
commit 993204b817
5 changed files with 5 additions and 112 deletions
-7
View File
@@ -1624,9 +1624,6 @@ HRESULT WrappedID3D12Device::Present(ID3D12GraphicsCommandList *pOverlayCommandL
rdcstr overlayText =
RenderDoc::Inst().GetOverlayText(RDCDriver::D3D12, m_FrameCounter, flags);
if(m_InvalidPSO)
overlayText += "ERROR: Invalid PSO created, likely using DXIL which is not supported.\n";
m_TextRenderer->RenderText(list, 0.0f, 0.0f, overlayText);
// transition backbuffer back again
@@ -1667,10 +1664,6 @@ HRESULT WrappedID3D12Device::Present(ID3D12GraphicsCommandList *pOverlayCommandL
if(!activeWindow)
return S_OK;
// disallow capturing if an invalid PSO has been created
if(m_InvalidPSO)
return S_OK;
// kill any current capture that isn't application defined
if(IsActiveCapturing(m_State) && !m_AppControlledCapture)
RenderDoc::Inst().EndFrameCapture((ID3D12Device *)this, swapper->GetHWND());
-2
View File
@@ -447,8 +447,6 @@ private:
bool m_AppControlledCapture = false;
bool m_InvalidPSO = false;
Threading::RWLock m_CapTransitionLock;
CaptureState m_State;
+2 -78
View File
@@ -403,33 +403,6 @@ bool WrappedID3D12Device::Serialise_CreateGraphicsPipelineState(
D3D12_GRAPHICS_PIPELINE_STATE_DESC unwrappedDesc = Descriptor;
unwrappedDesc.pRootSignature = Unwrap(unwrappedDesc.pRootSignature);
// check for bytecode - if the user is wrongly using DXIL we will fail to load the capture
{
D3D12_SHADER_BYTECODE *shaders[] = {
&unwrappedDesc.VS, &unwrappedDesc.HS, &unwrappedDesc.DS,
&unwrappedDesc.GS, &unwrappedDesc.PS,
};
const char *name[] = {"VS", "HS", "DS", "GS", "PS"};
for(size_t i = 0; i < ARRAY_COUNT(shaders); i++)
{
if(shaders[i]->BytecodeLength > 0 && shaders[i]->pShaderBytecode)
{
if(!DXBC::DXBCContainer::CheckForShaderCode(shaders[i]->pShaderBytecode,
shaders[i]->BytecodeLength))
{
RDCERR(
"No shader code found in %s bytecode in pipeline state. "
"DXIL is unsupported and must be checked for using CheckFeatureSupport.",
name[i]);
m_FailedReplayStatus = ReplayStatus::APIReplayFailed;
return false;
}
}
}
}
ID3D12PipelineState *ret = NULL;
HRESULT hr = m_pDevice->CreateGraphicsPipelineState(&unwrappedDesc, guid, (void **)&ret);
@@ -540,32 +513,6 @@ HRESULT WrappedID3D12Device::CreateGraphicsPipelineState(const D3D12_GRAPHICS_PI
if(SUCCEEDED(ret))
{
// check for bytecode - if the user is wrongly using DXIL we will prevent capturing
{
D3D12_SHADER_BYTECODE *shaders[] = {
&unwrappedDesc.VS, &unwrappedDesc.HS, &unwrappedDesc.DS,
&unwrappedDesc.GS, &unwrappedDesc.PS,
};
const char *name[] = {"VS", "HS", "DS", "GS", "PS"};
for(size_t i = 0; i < ARRAY_COUNT(shaders); i++)
{
if(shaders[i]->BytecodeLength > 0 && shaders[i]->pShaderBytecode)
{
if(!DXBC::DXBCContainer::CheckForShaderCode(shaders[i]->pShaderBytecode,
shaders[i]->BytecodeLength))
{
RDCERR(
"No shader code found in %s bytecode in pipeline state. "
"DXIL is unsupported and must be checked for using CheckFeatureSupport.",
name[i]);
m_InvalidPSO = true;
}
}
}
}
WrappedID3D12PipelineState *wrapped = new WrappedID3D12PipelineState(real, this);
if(IsCaptureMode(m_State))
@@ -673,18 +620,6 @@ bool WrappedID3D12Device::Serialise_CreateComputePipelineState(
D3D12_COMPUTE_PIPELINE_STATE_DESC unwrappedDesc = Descriptor;
unwrappedDesc.pRootSignature = Unwrap(unwrappedDesc.pRootSignature);
// check for bytecode - if the user is wrongly using DXIL we will hard-fail instead of producing
// a corrupted capture.
if(!DXBC::DXBCContainer::CheckForShaderCode(unwrappedDesc.CS.pShaderBytecode,
unwrappedDesc.CS.BytecodeLength))
{
RDCERR(
"No shader code found in CS bytecode in pipeline state. "
"DXIL is unsupported and must be checked for using CheckFeatureSupport.");
m_FailedReplayStatus = ReplayStatus::APIReplayFailed;
return false;
}
ID3D12PipelineState *ret = NULL;
HRESULT hr = m_pDevice->CreateComputePipelineState(&unwrappedDesc, guid, (void **)&ret);
@@ -738,17 +673,6 @@ HRESULT WrappedID3D12Device::CreateComputePipelineState(const D3D12_COMPUTE_PIPE
if(SUCCEEDED(ret))
{
// check for bytecode - if the user is wrongly using DXIL we will hard-fail instead of producing
// a corrupted capture.
if(!DXBC::DXBCContainer::CheckForShaderCode(unwrappedDesc.CS.pShaderBytecode,
unwrappedDesc.CS.BytecodeLength))
{
RDCERR(
"No shader code found in CS bytecode in pipeline state. "
"DXIL is unsupported and must be checked for using CheckFeatureSupport.");
m_InvalidPSO = true;
}
WrappedID3D12PipelineState *wrapped = new WrappedID3D12PipelineState(real, this);
if(IsCaptureMode(m_State))
@@ -2851,8 +2775,8 @@ HRESULT WrappedID3D12Device::CheckFeatureSupport(D3D12_FEATURE Feature, void *pF
if(FeatureSupportDataSize != sizeof(D3D12_FEATURE_DATA_SHADER_MODEL))
return E_INVALIDARG;
// don't support sm6.0 and over
model->HighestShaderModel = RDCMIN(model->HighestShaderModel, D3D_SHADER_MODEL_5_1);
// clamp SM to what we support
model->HighestShaderModel = RDCMIN(model->HighestShaderModel, D3D_SHADER_MODEL_6_6);
return S_OK;
}
@@ -698,31 +698,10 @@ bool DXBCContainer::CheckForDebugInfo(const void *ByteCode, size_t ByteCodeLengt
{
return true;
}
}
return false;
}
bool DXBCContainer::CheckForShaderCode(const void *ByteCode, size_t ByteCodeLength)
{
FileHeader *header = (FileHeader *)ByteCode;
char *data = (char *)ByteCode; // just for convenience
if(header->fourcc != FOURCC_DXBC)
return false;
if(header->fileLength != (uint32_t)ByteCodeLength)
return false;
uint32_t *chunkOffsets = (uint32_t *)(header + 1); // right after the header
for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++)
{
uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]);
if(*fourcc == FOURCC_SHEX || *fourcc == FOURCC_SHDR)
else if(*fourcc == FOURCC_ILDB)
{
return true;
}
}
return false;
@@ -195,7 +195,6 @@ public:
static void GetHash(uint32_t hash[4], const void *ByteCode, size_t BytecodeLength);
static bool CheckForDebugInfo(const void *ByteCode, size_t ByteCodeLength);
static bool CheckForShaderCode(const void *ByteCode, size_t ByteCodeLength);
static rdcstr GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLength);
private: