in DxDispatch/src/dxdispatch/HlslDispatchable.cpp [180:276]
void HlslDispatchable::CompileWithDxc()
{
ComPtr<IDxcBlobEncoding> source;
THROW_IF_FAILED(m_device->GetDxcUtils()->LoadFile(
m_desc.sourcePath.c_str(),
nullptr,
&source));
DxcBuffer sourceBuffer;
sourceBuffer.Ptr = source->GetBufferPointer();
sourceBuffer.Size = source->GetBufferSize();
sourceBuffer.Encoding = DXC_CP_ACP;
std::vector<std::wstring> compilerArgs(m_desc.compilerArgs.size());
std::vector<LPCWSTR> lpcwstrArgs(m_desc.compilerArgs.size());
for (size_t i = 0; i < m_desc.compilerArgs.size(); i++)
{
compilerArgs[i] = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(m_desc.compilerArgs[i]);
lpcwstrArgs[i] = compilerArgs[i].data();
}
ComPtr<IDxcResult> result;
THROW_IF_FAILED(m_device->GetDxcCompiler()->Compile(
&sourceBuffer,
lpcwstrArgs.data(),
static_cast<UINT32>(lpcwstrArgs.size()),
m_device->GetDxcIncludeHandler(),
IID_PPV_ARGS(&result)));
ComPtr<IDxcBlobUtf8> errors;
THROW_IF_FAILED(result->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&errors), nullptr));
if (errors != nullptr && errors->GetStringLength() != 0)
{
std::wcerr << L"Warnings and Errors:" << errors->GetStringPointer();
}
HRESULT compileStatus = S_OK;
THROW_IF_FAILED(result->GetStatus(&compileStatus));
if (FAILED(compileStatus))
{
throw std::invalid_argument("Failed to compile.");
}
ComPtr<IDxcBlob> shaderBlob;
THROW_IF_FAILED(result->GetOutput(
DXC_OUT_OBJECT,
IID_PPV_ARGS(&shaderBlob),
nullptr));
ComPtr<IDxcBlob> reflectionBlob;
THROW_IF_FAILED(result->GetOutput(
DXC_OUT_REFLECTION,
IID_PPV_ARGS(&reflectionBlob),
nullptr));
ComPtr<IDxcBlob> pdbBlob;
ComPtr<IDxcBlobUtf16> pdbName;
if (SUCCEEDED(result->GetOutput(
DXC_OUT_PDB,
IID_PPV_ARGS(&pdbBlob),
&pdbName)))
{
// TODO: store this in a temp directory?
FILE* fp = NULL;
_wfopen_s(&fp, pdbName->GetStringPointer(), L"wb");
fwrite(pdbBlob->GetBufferPointer(), pdbBlob->GetBufferSize(), 1, fp);
fclose(fp);
}
DxcBuffer reflectionBuffer;
reflectionBuffer.Ptr = reflectionBlob->GetBufferPointer();
reflectionBuffer.Size = reflectionBlob->GetBufferSize();
reflectionBuffer.Encoding = DXC_CP_ACP;
THROW_IF_FAILED(m_device->GetDxcUtils()->CreateReflection(
&reflectionBuffer,
IID_PPV_ARGS(m_shaderReflection.ReleaseAndGetAddressOf())));
CreateRootSignatureAndBindingMap();
D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.pRootSignature = m_rootSignature.Get();
psoDesc.CS.pShaderBytecode = shaderBlob->GetBufferPointer();
psoDesc.CS.BytecodeLength = shaderBlob->GetBufferSize();
THROW_IF_FAILED(m_device->D3D()->CreateComputePipelineState(
&psoDesc,
IID_PPV_ARGS(m_pipelineState.ReleaseAndGetAddressOf())));
ComPtr<ID3D12DescriptorHeap> descriptorHeap;
D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = {};
descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
descriptorHeapDesc.NumDescriptors = static_cast<uint32_t>(m_bindPoints.size());
descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
THROW_IF_FAILED(m_device->D3D()->CreateDescriptorHeap(
&descriptorHeapDesc,
IID_PPV_ARGS(m_descriptorHeap.ReleaseAndGetAddressOf())));
}