diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h --- a/llvm/include/llvm/BinaryFormat/DXContainer.h +++ b/llvm/include/llvm/BinaryFormat/DXContainer.h @@ -125,6 +125,14 @@ static_assert(sizeof(ProgramHeader) == 24, "ProgramHeader Size incorrect!"); +#define CONTAINER_PART(Part) Part, +enum class PartType { + Unknown = 0, +#include "DXContainerConstants.def" +}; + +PartType parsePartType(StringRef S); + } // namespace dxbc } // namespace llvm diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def @@ -0,0 +1,6 @@ + +#ifdef CONTAINER_PART +CONTAINER_PART(DXIL) + +#undef CONTAINER_PART +#endif diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h --- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h +++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h @@ -54,6 +54,8 @@ }; struct Part { + Part() = default; + Part(std::string N, uint32_t S) : Name(N), Size(S) {} std::string Name; uint32_t Size; Optional Program; diff --git a/llvm/lib/BinaryFormat/CMakeLists.txt b/llvm/lib/BinaryFormat/CMakeLists.txt --- a/llvm/lib/BinaryFormat/CMakeLists.txt +++ b/llvm/lib/BinaryFormat/CMakeLists.txt @@ -2,6 +2,7 @@ AMDGPUMetadataVerifier.cpp COFF.cpp Dwarf.cpp + DXContainer.cpp ELF.cpp MachO.cpp Magic.cpp diff --git a/llvm/lib/BinaryFormat/DXContainer.cpp b/llvm/lib/BinaryFormat/DXContainer.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/BinaryFormat/DXContainer.cpp @@ -0,0 +1,25 @@ + +//===-- llvm/BinaryFormat/DXContainer.cpp - DXContainer Utils ----*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains utility functions for working with DXContainers. +// +//===----------------------------------------------------------------------===// + +#include "llvm/BinaryFormat/DXContainer.h" +#include "llvm/ADT/StringSwitch.h" + +using namespace llvm; +using namespace llvm; + +dxbc::PartType dxbc::parsePartType(StringRef S) { +#define CONTAINER_PART(PartName) .Case(#PartName, PartType::PartName) + return StringSwitch(S) +#include "llvm/BinaryFormat/DXContainerConstants.def" + .Default(dxbc::PartType::Unknown); +} diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp --- a/llvm/lib/Object/DXContainer.cpp +++ b/llvm/lib/Object/DXContainer.cpp @@ -81,11 +81,16 @@ return parseFailed("Part offset points beyond boundary of the file"); PartOffsets.push_back(PartOffset); - // If this isn't a dxil part stop here... - if (Data.getBuffer().substr(PartOffset, 4) != "DXIL") - continue; - if (Error Err = parseDXILHeader(PartOffset + sizeof(dxbc::PartHeader))) - return Err; + dxbc::PartType PT = + dxbc::parsePartType(Data.getBuffer().substr(PartOffset, 4)); + switch (PT) { + case dxbc::PartType::DXIL: + if (Error Err = parseDXILHeader(PartOffset + sizeof(dxbc::PartHeader))) + return Err; + break; + case dxbc::PartType::Unknown: + break; + } } return Error::success(); } diff --git a/llvm/tools/obj2yaml/dxcontainer2yaml.cpp b/llvm/tools/obj2yaml/dxcontainer2yaml.cpp --- a/llvm/tools/obj2yaml/dxcontainer2yaml.cpp +++ b/llvm/tools/obj2yaml/dxcontainer2yaml.cpp @@ -38,23 +38,30 @@ Obj->Header.PartOffsets = std::vector(); for (const auto P : Container) { Obj->Header.PartOffsets->push_back(P.Offset); - if (P.Part.getName() == "DXIL") { + Obj->Parts.push_back( + DXContainerYAML::Part(P.Part.getName().str(), P.Part.Size)); + DXContainerYAML::Part &NewPart = Obj->Parts.back(); + dxbc::PartType PT = dxbc::parsePartType(P.Part.getName()); + switch (PT) { + case dxbc::PartType::DXIL: { Optional DXIL = Container.getDXIL(); assert(DXIL && "Since we are iterating and found a DXIL part, " "this should never not have a value"); - Obj->Parts.push_back(DXContainerYAML::Part{ - P.Part.getName().str(), P.Part.Size, - DXContainerYAML::DXILProgram{ - DXIL->first.MajorVersion, DXIL->first.MinorVersion, - DXIL->first.ShaderKind, DXIL->first.Size, - DXIL->first.Bitcode.MajorVersion, - DXIL->first.Bitcode.MinorVersion, DXIL->first.Bitcode.Offset, - DXIL->first.Bitcode.Size, - std::vector( - DXIL->second, DXIL->second + DXIL->first.Bitcode.Size)}}); - } else { - Obj->Parts.push_back( - DXContainerYAML::Part{P.Part.getName().str(), P.Part.Size, None}); + NewPart.Program = DXContainerYAML::DXILProgram{ + DXIL->first.MajorVersion, + DXIL->first.MinorVersion, + DXIL->first.ShaderKind, + DXIL->first.Size, + DXIL->first.Bitcode.MajorVersion, + DXIL->first.Bitcode.MinorVersion, + DXIL->first.Bitcode.Offset, + DXIL->first.Bitcode.Size, + std::vector( + DXIL->second, DXIL->second + DXIL->first.Bitcode.Size)}; + break; + } + case dxbc::PartType::Unknown: + break; } }