mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-13 18:21:01 +00:00
308 lines
11 KiB
C++
308 lines
11 KiB
C++
/******************************************************************************
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2019-2020 Baldur Karlsson
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
#include "d3d12_device.h"
|
|
#include "driver/dxgi/dxgi_common.h"
|
|
#include "d3d12_resources.h"
|
|
|
|
template <typename SerialiserType>
|
|
bool WrappedID3D12Device::Serialise_CreatePipelineState(SerialiserType &ser,
|
|
const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc,
|
|
REFIID riid, void **ppPipelineState)
|
|
{
|
|
SERIALISE_ELEMENT_LOCAL(Descriptor, D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(*pDesc))
|
|
.Named("pDesc"_lit);
|
|
SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit);
|
|
SERIALISE_ELEMENT_LOCAL(pPipelineState,
|
|
((WrappedID3D12PipelineState *)*ppPipelineState)->GetResourceID())
|
|
.TypedAs("ID3D12PipelineState *"_lit);
|
|
|
|
SERIALISE_CHECK_READ_ERRORS();
|
|
|
|
if(IsReplayingAndReading())
|
|
{
|
|
D3D12_PACKED_PIPELINE_STATE_STREAM_DESC unwrappedDesc(Descriptor);
|
|
unwrappedDesc.Unwrap();
|
|
|
|
ID3D12PipelineState *ret = NULL;
|
|
HRESULT hr = E_NOINTERFACE;
|
|
|
|
if(m_pDevice2)
|
|
hr = m_pDevice2->CreatePipelineState(unwrappedDesc.AsDescStream(), guid, (void **)&ret);
|
|
else
|
|
RDCERR("Replaying a without D3D12.2 available");
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
RDCERR("Failed on resource serialise-creation, HRESULT: %s", ToStr(hr).c_str());
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
ret = new WrappedID3D12PipelineState(ret, this);
|
|
|
|
WrappedID3D12PipelineState *wrapped = (WrappedID3D12PipelineState *)ret;
|
|
|
|
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC *storedDesc =
|
|
new D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(Descriptor);
|
|
|
|
D3D12_SHADER_BYTECODE *shaders[] = {
|
|
&storedDesc->VS, &storedDesc->HS, &storedDesc->DS,
|
|
&storedDesc->GS, &storedDesc->PS, &storedDesc->CS,
|
|
};
|
|
|
|
AddResource(pPipelineState, ResourceType::PipelineState, "Pipeline State");
|
|
DerivedResource(Descriptor.pRootSignature, pPipelineState);
|
|
|
|
for(size_t i = 0; i < ARRAY_COUNT(shaders); i++)
|
|
{
|
|
if(shaders[i]->BytecodeLength == 0 || shaders[i]->pShaderBytecode == NULL)
|
|
{
|
|
shaders[i]->pShaderBytecode = NULL;
|
|
shaders[i]->BytecodeLength = 0;
|
|
}
|
|
else
|
|
{
|
|
WrappedID3D12Shader *entry = WrappedID3D12Shader::AddShader(*shaders[i], this);
|
|
entry->AddRef();
|
|
|
|
shaders[i]->pShaderBytecode = entry;
|
|
|
|
AddResourceCurChunk(entry->GetResourceID());
|
|
|
|
DerivedResource(entry->GetResourceID(), pPipelineState);
|
|
}
|
|
}
|
|
|
|
if(storedDesc->CS.BytecodeLength > 0)
|
|
{
|
|
wrapped->compute = storedDesc;
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics = storedDesc;
|
|
|
|
if(wrapped->graphics->InputLayout.NumElements)
|
|
{
|
|
wrapped->graphics->InputLayout.pInputElementDescs =
|
|
new D3D12_INPUT_ELEMENT_DESC[wrapped->graphics->InputLayout.NumElements];
|
|
memcpy((void *)wrapped->graphics->InputLayout.pInputElementDescs,
|
|
Descriptor.InputLayout.pInputElementDescs,
|
|
sizeof(D3D12_INPUT_ELEMENT_DESC) * wrapped->graphics->InputLayout.NumElements);
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics->InputLayout.pInputElementDescs = NULL;
|
|
}
|
|
|
|
if(wrapped->graphics->StreamOutput.NumEntries)
|
|
{
|
|
wrapped->graphics->StreamOutput.pSODeclaration =
|
|
new D3D12_SO_DECLARATION_ENTRY[wrapped->graphics->StreamOutput.NumEntries];
|
|
memcpy((void *)wrapped->graphics->StreamOutput.pSODeclaration,
|
|
Descriptor.StreamOutput.pSODeclaration,
|
|
sizeof(D3D12_SO_DECLARATION_ENTRY) * wrapped->graphics->StreamOutput.NumEntries);
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics->StreamOutput.pSODeclaration = NULL;
|
|
}
|
|
|
|
if(wrapped->graphics->StreamOutput.NumStrides)
|
|
{
|
|
wrapped->graphics->StreamOutput.pBufferStrides =
|
|
new UINT[wrapped->graphics->StreamOutput.NumStrides];
|
|
memcpy((void *)wrapped->graphics->StreamOutput.pBufferStrides,
|
|
Descriptor.StreamOutput.pBufferStrides,
|
|
sizeof(UINT) * wrapped->graphics->StreamOutput.NumStrides);
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics->StreamOutput.pBufferStrides = NULL;
|
|
}
|
|
|
|
if(wrapped->graphics->ViewInstancing.ViewInstanceCount)
|
|
{
|
|
wrapped->graphics->ViewInstancing.pViewInstanceLocations =
|
|
new D3D12_VIEW_INSTANCE_LOCATION[wrapped->graphics->ViewInstancing.ViewInstanceCount];
|
|
memcpy((void *)wrapped->graphics->ViewInstancing.pViewInstanceLocations,
|
|
Descriptor.ViewInstancing.pViewInstanceLocations,
|
|
sizeof(D3D12_VIEW_INSTANCE_LOCATION) *
|
|
wrapped->graphics->ViewInstancing.ViewInstanceCount);
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics->ViewInstancing.pViewInstanceLocations = NULL;
|
|
}
|
|
}
|
|
|
|
GetResourceManager()->AddLiveResource(pPipelineState, ret);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
HRESULT WrappedID3D12Device::CreatePipelineState(const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc,
|
|
REFIID riid, void **ppPipelineState)
|
|
{
|
|
if(pDesc == NULL)
|
|
return m_pDevice3->CreatePipelineState(pDesc, riid, ppPipelineState);
|
|
|
|
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC expandedDesc = *pDesc;
|
|
D3D12_PACKED_PIPELINE_STATE_STREAM_DESC unwrappedDesc = expandedDesc;
|
|
unwrappedDesc.Unwrap();
|
|
|
|
if(ppPipelineState == NULL)
|
|
return m_pDevice3->CreatePipelineState(unwrappedDesc.AsDescStream(), riid, ppPipelineState);
|
|
|
|
if(riid != __uuidof(ID3D12PipelineState))
|
|
return E_NOINTERFACE;
|
|
|
|
ID3D12PipelineState *real = NULL;
|
|
HRESULT ret;
|
|
SERIALISE_TIME_CALL(
|
|
ret = m_pDevice3->CreatePipelineState(unwrappedDesc.AsDescStream(), riid, (void **)&real));
|
|
|
|
if(SUCCEEDED(ret))
|
|
{
|
|
WrappedID3D12PipelineState *wrapped = new WrappedID3D12PipelineState(real, this);
|
|
|
|
if(IsCaptureMode(m_State))
|
|
{
|
|
CACHE_THREAD_SERIALISER();
|
|
|
|
SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreatePipelineState);
|
|
Serialise_CreatePipelineState(ser, pDesc, riid, (void **)&wrapped);
|
|
|
|
D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID());
|
|
record->type = Resource_PipelineState;
|
|
record->Length = 0;
|
|
wrapped->SetResourceRecord(record);
|
|
|
|
if(expandedDesc.pRootSignature)
|
|
record->AddParent(GetRecord(expandedDesc.pRootSignature));
|
|
|
|
record->AddChunk(scope.Get());
|
|
}
|
|
else
|
|
{
|
|
GetResourceManager()->AddLiveResource(wrapped->GetResourceID(), wrapped);
|
|
|
|
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC *storedDesc =
|
|
new D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(expandedDesc);
|
|
|
|
D3D12_SHADER_BYTECODE *shaders[] = {
|
|
&storedDesc->VS, &storedDesc->HS, &storedDesc->DS,
|
|
&storedDesc->GS, &storedDesc->PS, &storedDesc->CS,
|
|
};
|
|
|
|
for(size_t i = 0; i < ARRAY_COUNT(shaders); i++)
|
|
{
|
|
if(shaders[i]->BytecodeLength == 0 || shaders[i]->pShaderBytecode == NULL)
|
|
{
|
|
shaders[i]->pShaderBytecode = NULL;
|
|
shaders[i]->BytecodeLength = 0;
|
|
}
|
|
else
|
|
{
|
|
WrappedID3D12Shader *sh = WrappedID3D12Shader::AddShader(*shaders[i], this);
|
|
sh->AddRef();
|
|
shaders[i]->pShaderBytecode = sh;
|
|
}
|
|
}
|
|
|
|
if(storedDesc->CS.BytecodeLength > 0)
|
|
{
|
|
wrapped->compute = storedDesc;
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics = storedDesc;
|
|
|
|
if(wrapped->graphics->InputLayout.NumElements)
|
|
{
|
|
wrapped->graphics->InputLayout.pInputElementDescs =
|
|
new D3D12_INPUT_ELEMENT_DESC[wrapped->graphics->InputLayout.NumElements];
|
|
memcpy((void *)wrapped->graphics->InputLayout.pInputElementDescs,
|
|
expandedDesc.InputLayout.pInputElementDescs,
|
|
sizeof(D3D12_INPUT_ELEMENT_DESC) * wrapped->graphics->InputLayout.NumElements);
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics->InputLayout.pInputElementDescs = NULL;
|
|
}
|
|
|
|
if(wrapped->graphics->StreamOutput.NumEntries)
|
|
{
|
|
wrapped->graphics->StreamOutput.pSODeclaration =
|
|
new D3D12_SO_DECLARATION_ENTRY[wrapped->graphics->StreamOutput.NumEntries];
|
|
memcpy((void *)wrapped->graphics->StreamOutput.pSODeclaration,
|
|
expandedDesc.StreamOutput.pSODeclaration,
|
|
sizeof(D3D12_SO_DECLARATION_ENTRY) * wrapped->graphics->StreamOutput.NumEntries);
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics->StreamOutput.pSODeclaration = NULL;
|
|
}
|
|
|
|
if(wrapped->graphics->StreamOutput.NumStrides)
|
|
{
|
|
wrapped->graphics->StreamOutput.pBufferStrides =
|
|
new UINT[wrapped->graphics->StreamOutput.NumStrides];
|
|
memcpy((void *)wrapped->graphics->StreamOutput.pBufferStrides,
|
|
expandedDesc.StreamOutput.pBufferStrides,
|
|
sizeof(UINT) * wrapped->graphics->StreamOutput.NumStrides);
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics->StreamOutput.pBufferStrides = NULL;
|
|
}
|
|
|
|
if(wrapped->graphics->ViewInstancing.ViewInstanceCount)
|
|
{
|
|
wrapped->graphics->ViewInstancing.pViewInstanceLocations =
|
|
new D3D12_VIEW_INSTANCE_LOCATION[wrapped->graphics->ViewInstancing.ViewInstanceCount];
|
|
memcpy((void *)wrapped->graphics->ViewInstancing.pViewInstanceLocations,
|
|
expandedDesc.ViewInstancing.pViewInstanceLocations,
|
|
sizeof(D3D12_VIEW_INSTANCE_LOCATION) *
|
|
wrapped->graphics->ViewInstancing.ViewInstanceCount);
|
|
}
|
|
else
|
|
{
|
|
wrapped->graphics->ViewInstancing.pViewInstanceLocations = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
*ppPipelineState = (ID3D12PipelineState *)wrapped;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
INSTANTIATE_FUNCTION_SERIALISED(HRESULT, WrappedID3D12Device, CreatePipelineState,
|
|
const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, REFIID riid,
|
|
void **ppPipelineState);
|