1 //===------ dxcontainer2yaml.cpp - obj2yaml conversion tool -----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "llvm/Object/DXContainer.h"
11 #include "llvm/ObjectYAML/DXContainerYAML.h"
12 #include "llvm/Support/Error.h"
17 using namespace llvm::object
;
19 static Expected
<DXContainerYAML::Object
*>
20 dumpDXContainer(MemoryBufferRef Source
) {
21 assert(file_magic::dxcontainer_object
== identify_magic(Source
.getBuffer()));
23 Expected
<DXContainer
> ExDXC
= DXContainer::create(Source
);
25 return ExDXC
.takeError();
26 DXContainer Container
= *ExDXC
;
28 std::unique_ptr
<DXContainerYAML::Object
> Obj
=
29 std::make_unique
<DXContainerYAML::Object
>();
31 for (uint8_t Byte
: Container
.getHeader().FileHash
.Digest
)
32 Obj
->Header
.Hash
.push_back(Byte
);
33 Obj
->Header
.Version
.Major
= Container
.getHeader().Version
.Major
;
34 Obj
->Header
.Version
.Minor
= Container
.getHeader().Version
.Minor
;
35 Obj
->Header
.FileSize
= Container
.getHeader().FileSize
;
36 Obj
->Header
.PartCount
= Container
.getHeader().PartCount
;
38 Obj
->Header
.PartOffsets
= std::vector
<uint32_t>();
39 for (const auto P
: Container
) {
40 Obj
->Header
.PartOffsets
->push_back(P
.Offset
);
42 DXContainerYAML::Part(P
.Part
.getName().str(), P
.Part
.Size
));
43 DXContainerYAML::Part
&NewPart
= Obj
->Parts
.back();
44 dxbc::PartType PT
= dxbc::parsePartType(P
.Part
.getName());
46 case dxbc::PartType::DXIL
: {
47 std::optional
<DXContainer::DXILData
> DXIL
= Container
.getDXIL();
48 assert(DXIL
&& "Since we are iterating and found a DXIL part, "
49 "this should never not have a value");
50 NewPart
.Program
= DXContainerYAML::DXILProgram
{
51 DXIL
->first
.MajorVersion
,
52 DXIL
->first
.MinorVersion
,
53 DXIL
->first
.ShaderKind
,
55 DXIL
->first
.Bitcode
.MajorVersion
,
56 DXIL
->first
.Bitcode
.MinorVersion
,
57 DXIL
->first
.Bitcode
.Offset
,
58 DXIL
->first
.Bitcode
.Size
,
59 std::vector
<llvm::yaml::Hex8
>(
60 DXIL
->second
, DXIL
->second
+ DXIL
->first
.Bitcode
.Size
)};
63 case dxbc::PartType::SFI0
: {
64 std::optional
<uint64_t> Flags
= Container
.getShaderFlags();
65 // Omit the flags in the YAML if they are missing or zero.
66 if (Flags
&& *Flags
> 0)
67 NewPart
.Flags
= DXContainerYAML::ShaderFlags(*Flags
);
70 case dxbc::PartType::HASH
: {
71 std::optional
<dxbc::ShaderHash
> Hash
= Container
.getShaderHash();
72 if (Hash
&& Hash
->isPopulated())
73 NewPart
.Hash
= DXContainerYAML::ShaderHash(*Hash
);
76 case dxbc::PartType::PSV0
: {
77 const auto &PSVInfo
= Container
.getPSVInfo();
81 std::get_if
<dxbc::PSV::v0::RuntimeInfo
>(&PSVInfo
->getInfo())) {
82 if (!Container
.getDXIL())
85 DXContainerYAML::PSVInfo(P
, Container
.getDXIL()->first
.ShaderKind
);
86 } else if (const auto *P
= std::get_if
<dxbc::PSV::v1::RuntimeInfo
>(
88 NewPart
.Info
= DXContainerYAML::PSVInfo(P
);
89 else if (const auto *P
=
90 std::get_if
<dxbc::PSV::v2::RuntimeInfo
>(&PSVInfo
->getInfo()))
91 NewPart
.Info
= DXContainerYAML::PSVInfo(P
);
92 for (auto Res
: PSVInfo
->getResources())
93 NewPart
.Info
->Resources
.push_back(Res
);
96 case dxbc::PartType::Unknown
:
101 return Obj
.release();
104 llvm::Error
dxcontainer2yaml(llvm::raw_ostream
&Out
,
105 llvm::MemoryBufferRef Source
) {
106 Expected
<DXContainerYAML::Object
*> YAMLOrErr
= dumpDXContainer(Source
);
108 return YAMLOrErr
.takeError();
110 std::unique_ptr
<DXContainerYAML::Object
> YAML(YAMLOrErr
.get());
111 yaml::Output
Yout(Out
);
114 return Error::success();