18 return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
24 if (Src < Buffer.
begin() || Src +
sizeof(
T) > Buffer.
end())
25 return parseFailed(
"Reading structure out of file bounds");
27 memcpy(&
Struct, Src,
sizeof(
T));
36 Twine Str =
"structure") {
37 static_assert(std::is_integral_v<T>,
38 "Cannot call readInteger on non-integral type.");
40 if (Src < Buffer.
begin() || Src +
sizeof(
T) > Buffer.
end())
46 if (
reinterpret_cast<uintptr_t
>(Src) %
alignof(
T) != 0)
47 memcpy(
reinterpret_cast<char *
>(&Val), Src,
sizeof(
T));
49 Val = *
reinterpret_cast<const T *
>(Src);
58Error DXContainer::parseHeader() {
64 return parseFailed(
"More than one DXIL part is present in the file");
65 const char *Current = Part.
begin();
70 DXIL.emplace(std::make_pair(Header, Current));
76 return parseFailed(
"More than one SFI0 part is present in the file");
80 ShaderFlags = FlagValue;
86 return parseFailed(
"More than one HASH part is present in the file");
96 return parseFailed(
"More than one PSV0 part is present in the file");
103Error DXContainer::parsePartOffsets() {
107 for (
uint32_t Part = 0; Part < Header.PartCount; ++Part) {
111 if (PartOffset < LastOffset)
114 "Part offset for part {0} begins before the previous part ends",
119 return parseFailed(
"Part offset points beyond boundary of the file");
126 return parseFailed(
"File not large enough to read part name");
135 PartSize,
"part size"))
138 LastOffset = PartOffset + PartSize;
140 case dxbc::PartType::DXIL:
141 if (
Error Err = parseDXILHeader(PartData))
144 case dxbc::PartType::SFI0:
145 if (
Error Err = parseShaderFlags(PartData))
148 case dxbc::PartType::HASH:
149 if (
Error Err = parseHash(PartData))
152 case dxbc::PartType::PSV0:
153 if (
Error Err = parsePSVInfo(PartData))
165 return parseFailed(
"Cannot fully parse pipeline state validation "
166 "information without DXIL part.");
167 if (
Error Err = PSVInfo->parse(DXIL->first.ShaderKind))
175 if (
Error Err = Container.parseHeader())
176 return std::move(Err);
177 if (
Error Err = Container.parsePartOffsets())
178 return std::move(Err);
182void DXContainer::PartIterator::updateIteratorImpl(
const uint32_t Offset) {
190 IteratorState.Offset =
Offset;
196 const char *Current = Data.begin();
203 using namespace dxbc::PSV;
205 const uint32_t PSVVersion = getVersion();
208 if (PSVVersion == 2) {
209 v2::RuntimeInfo
Info;
213 Info.swapBytes(ShaderStage);
215 }
else if (PSVVersion == 1) {
216 v1::RuntimeInfo
Info;
220 Info.swapBytes(ShaderStage);
223 v0::RuntimeInfo
Info;
227 Info.swapBytes(ShaderStage);
237 Resources.Stride = (PSVVersion < 2) ?
sizeof(v0::ResourceBindInfo)
238 :
sizeof(v2::ResourceBindInfo);
239 size_t BindingDataSize = Resources.Stride * ResourceCount;
240 Resources.Data = Data.substr(Current - Data.begin(), BindingDataSize);
242 Current += BindingDataSize;
#define offsetof(TYPE, MEMBER)
Analysis containing CSE Info
static Error parseFailed(const Twine &Msg)
static Error readStruct(StringRef Buffer, const char *Src, T &Struct)
static Error readInteger(StringRef Buffer, const char *Src, T &Val, Twine Str="structure")
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
size_t getBufferSize() const
const char * getBufferStart() const
StringRef getBuffer() const
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Expected< DXContainer > create(MemoryBufferRef Object)
Error parse(uint16_t ShaderKind)
PartType parsePartType(StringRef S)
Triple::EnvironmentType getShaderStage(uint32_t Kind)
constexpr bool IsBigEndianHost
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.