LLVM: lib/Object/DXContainer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

14

15using namespace llvm;

17

19 return make_error(Msg.str(), object_error::parse_failed);

20}

21

22template

24

25 if (Src < Buffer.begin() || Src + sizeof(T) > Buffer.end())

26 return parseFailed("Reading structure out of file bounds");

27

28 memcpy(&Struct, Src, sizeof(T));

29

33}

34

35template

37 Twine Str = "structure") {

38 static_assert(std::is_integral_v,

39 "Cannot call readInteger on non-integral type.");

40

41 if (Src < Buffer.begin() || Src + sizeof(T) > Buffer.end())

42 return parseFailed(Twine("Reading ") + Str + " out of file bounds");

43

44

45

46

47 if (reinterpret_cast<uintptr_t>(Src) % alignof(T) != 0)

48 memcpy(reinterpret_cast<char *>(&Val), Src, sizeof(T));

49 else

50 Val = *reinterpret_cast<const T *>(Src);

51

55}

56

58

59Error DXContainer::parseHeader() {

61}

62

64 if (DXIL)

65 return parseFailed("More than one DXIL part is present in the file");

66 const char *Current = Part.begin();

69 return Err;

71 DXIL.emplace(std::make_pair(Header, Current));

73}

74

75Error DXContainer::parseShaderFeatureFlags(StringRef Part) {

76 if (ShaderFeatureFlags)

77 return parseFailed("More than one SFI0 part is present in the file");

80 return Err;

81 ShaderFeatureFlags = FlagValue;

83}

84

86 if (Hash)

87 return parseFailed("More than one HASH part is present in the file");

90 return Err;

91 Hash = ReadHash;

93}

94

96 if (PSVInfo)

97 return parseFailed("More than one PSV0 part is present in the file");

99

100

102}

103

107 return Err;

109

111 return parseFailed("Signature parameters extend beyond the part boundary");

112

114

117

118 for (const auto &Param : Parameters) {

120 return parseFailed("Invalid parameter name offset: name starts before "

121 "the first name offset");

123 return parseFailed("Invalid parameter name offset: name starts after the "

124 "end of the part data");

125 }

127}

128

129Error DXContainer::parsePartOffsets() {

132 const char *Current = Data.getBuffer().data() + sizeof(dxbc::Header);

133 for (uint32_t Part = 0; Part < Header.PartCount; ++Part) {

136 return Err;

137 if (PartOffset < LastOffset)

140 "Part offset for part {0} begins before the previous part ends",

141 Part)

142 .str());

144 if (PartOffset >= Data.getBufferSize())

145 return parseFailed("Part offset points beyond boundary of the file");

146

147

148

149

150

152 return parseFailed("File not large enough to read part name");

153 PartOffsets.push_back(PartOffset);

154

160 Data.getBufferStart() + PartOffset + 4,

161 PartSize, "part size"))

162 return Err;

163 StringRef PartData = Data.getBuffer().substr(PartDataStart, PartSize);

164 LastOffset = PartOffset + PartSize;

165 switch (PT) {

166 case dxbc::PartType::DXIL:

167 if (Error Err = parseDXILHeader(PartData))

168 return Err;

169 break;

170 case dxbc::PartType::SFI0:

171 if (Error Err = parseShaderFeatureFlags(PartData))

172 return Err;

173 break;

174 case dxbc::PartType::HASH:

175 if (Error Err = parseHash(PartData))

176 return Err;

177 break;

178 case dxbc::PartType::PSV0:

179 if (Error Err = parsePSVInfo(PartData))

180 return Err;

181 break;

182 case dxbc::PartType::ISG1:

183 if (Error Err = InputSignature.initialize(PartData))

184 return Err;

185 break;

186 case dxbc::PartType::OSG1:

187 if (Error Err = OutputSignature.initialize(PartData))

188 return Err;

189 break;

190 case dxbc::PartType::PSG1:

191 if (Error Err = PatchConstantSignature.initialize(PartData))

192 return Err;

193 break;

195 break;

196 }

197 }

198

199

200

201 if (PSVInfo) {

202 if (!DXIL)

203 return parseFailed("Cannot fully parse pipeline state validation "

204 "information without DXIL part.");

205 if (Error Err = PSVInfo->parse(DXIL->first.ShaderKind))

206 return Err;

207 }

209}

210

213 if (Error Err = Container.parseHeader())

214 return std::move(Err);

215 if (Error Err = Container.parsePartOffsets())

216 return std::move(Err);

217 return Container;

218}

219

220void DXContainer::PartIterator::updateIteratorImpl(const uint32_t Offset) {

221 StringRef Buffer = Container.Data.getBuffer();

222 const char *Current = Buffer.data() + Offset;

223

224

226 IteratorState.Data =

228 IteratorState.Offset = Offset;

229}

230

233

234 const char *Current = Data.begin();

236 return Err;

238

240

241 if (PSVInfoData.size() < Size)

243 "Pipeline state data extends beyond the bounds of the part");

244

245 using namespace dxbc::PSV;

246

247 const uint32_t PSVVersion = getVersion();

248

249

250 if (PSVVersion == 3) {

251 v3::RuntimeInfo Info;

253 return Err;

255 Info.swapBytes(ShaderStage);

256 BasicInfo = Info;

257 } else if (PSVVersion == 2) {

258 v2::RuntimeInfo Info;

260 return Err;

262 Info.swapBytes(ShaderStage);

263 BasicInfo = Info;

264 } else if (PSVVersion == 1) {

265 v1::RuntimeInfo Info;

267 return Err;

269 Info.swapBytes(ShaderStage);

270 BasicInfo = Info;

271 } else if (PSVVersion == 0) {

272 v0::RuntimeInfo Info;

274 return Err;

276 Info.swapBytes(ShaderStage);

277 BasicInfo = Info;

278 } else

280 "Cannot read PSV Runtime Info, unsupported PSV version.");

281

282 Current += Size;

283

286 return Err;

288

289 if (ResourceCount > 0) {

291 return Err;

293

294 size_t BindingDataSize = Resources.Stride * ResourceCount;

295 Resources.Data = Data.substr(Current - Data.begin(), BindingDataSize);

296

297 if (Resources.Data.size() < BindingDataSize)

299 "Resource binding data extends beyond the bounds of the part");

300

301 Current += BindingDataSize;

302 } else

303 Resources.Stride = sizeof(v2::ResourceBindInfo);

304

305

306 if (PSVVersion == 0)

308

309

310 Current = reinterpret_cast<const char *>(

311 alignTo<4>(reinterpret_cast<uintptr_t>(Current)));

312

313 uint32_t StringTableSize = 0;

315 return Err;

316 if (StringTableSize % 4 != 0)

317 return parseFailed("String table misaligned");

320

321 Current += StringTableSize;

322

323 uint32_t SemanticIndexTableSize = 0;

325 return Err;

327

328 SemanticIndexTable.reserve(SemanticIndexTableSize);

329 for (uint32_t I = 0; I < SemanticIndexTableSize; ++I) {

332 return Err;

334 SemanticIndexTable.push_back(Index);

335 }

336

337 uint8_t InputCount = getSigInputCount();

338 uint8_t OutputCount = getSigOutputCount();

339 uint8_t PatchOrPrimCount = getSigPatchOrPrimCount();

340

342

345 return Err;

347

348 SigOutputElements.Stride = SigPatchOrPrimElements.Stride =

349 SigInputElements.Stride;

350

351 if (Data.end() - Current <

354 "Signature elements extend beyond the size of the part");

355

356 size_t InputSize = SigInputElements.Stride * InputCount;

357 SigInputElements.Data = Data.substr(Current - Data.begin(), InputSize);

358 Current += InputSize;

359

360 size_t OutputSize = SigOutputElements.Stride * OutputCount;

361 SigOutputElements.Data = Data.substr(Current - Data.begin(), OutputSize);

362 Current += OutputSize;

363

364 size_t PSize = SigPatchOrPrimElements.Stride * PatchOrPrimCount;

365 SigPatchOrPrimElements.Data = Data.substr(Current - Data.begin(), PSize);

366 Current += PSize;

367 }

368

370 uint8_t PatchConstOrPrimVectorCount = getPatchConstOrPrimVectorCount();

371 uint8_t InputVectorCount = getInputVectorCount();

372

375 };

376

378 return maskDwordSize(Y) * X * 4;

379 };

380

381 if (usesViewID()) {

382 for (uint32_t I = 0; I < OutputVectorCounts.size(); ++I) {

383

384

385

387 maskDwordSize(static_cast<uint32_t>(OutputVectorCounts[I]));

388 size_t NumBytes = NumDwords * sizeof(uint32_t);

389 OutputVectorMasks[I].Data = Data.substr(Current - Data.begin(), NumBytes);

390 Current += NumBytes;

391 }

392

393 if (ShaderStage == Triple::Hull && PatchConstOrPrimVectorCount > 0) {

394 uint32_t NumDwords = maskDwordSize(PatchConstOrPrimVectorCount);

395 size_t NumBytes = NumDwords * sizeof(uint32_t);

396 PatchOrPrimMasks.Data = Data.substr(Current - Data.begin(), NumBytes);

397 Current += NumBytes;

398 }

399 }

400

401

402 for (uint32_t I = 0; I < OutputVectorCounts.size(); ++I) {

403 if (InputVectorCount == 0 || OutputVectorCounts[I] == 0)

404 continue;

405 uint32_t NumDwords = mapTableSize(InputVectorCount, OutputVectorCounts[I]);

406 size_t NumBytes = NumDwords * sizeof(uint32_t);

407 InputOutputMap[I].Data = Data.substr(Current - Data.begin(), NumBytes);

408 Current += NumBytes;

409 }

410

411

412 if (ShaderStage == Triple::Hull && PatchConstOrPrimVectorCount > 0 &&

413 InputVectorCount > 0) {

415 mapTableSize(InputVectorCount, PatchConstOrPrimVectorCount);

416 size_t NumBytes = NumDwords * sizeof(uint32_t);

417 InputPatchMap.Data = Data.substr(Current - Data.begin(), NumBytes);

418 Current += NumBytes;

419 }

420

421

422 if (ShaderStage == Triple::Domain && PatchConstOrPrimVectorCount > 0 &&

423 OutputVectorCounts[0] > 0) {

425 mapTableSize(PatchConstOrPrimVectorCount, OutputVectorCounts[0]);

426 size_t NumBytes = NumDwords * sizeof(uint32_t);

427 PatchOutputMap.Data = Data.substr(Current - Data.begin(), NumBytes);

428 Current += NumBytes;

429 }

430

432}

433

435 if (const auto *P = std::get_ifdxbc::PSV::v3::RuntimeInfo(&BasicInfo))

436 return P->SigInputElements;

437 if (const auto *P = std::get_ifdxbc::PSV::v2::RuntimeInfo(&BasicInfo))

438 return P->SigInputElements;

439 if (const auto *P = std::get_ifdxbc::PSV::v1::RuntimeInfo(&BasicInfo))

440 return P->SigInputElements;

441 return 0;

442}

443

445 if (const auto *P = std::get_ifdxbc::PSV::v3::RuntimeInfo(&BasicInfo))

446 return P->SigOutputElements;

447 if (const auto *P = std::get_ifdxbc::PSV::v2::RuntimeInfo(&BasicInfo))

448 return P->SigOutputElements;

449 if (const auto *P = std::get_ifdxbc::PSV::v1::RuntimeInfo(&BasicInfo))

450 return P->SigOutputElements;

451 return 0;

452}

453

455 if (const auto *P = std::get_ifdxbc::PSV::v3::RuntimeInfo(&BasicInfo))

456 return P->SigPatchOrPrimElements;

457 if (const auto *P = std::get_ifdxbc::PSV::v2::RuntimeInfo(&BasicInfo))

458 return P->SigPatchOrPrimElements;

459 if (const auto *P = std::get_ifdxbc::PSV::v1::RuntimeInfo(&BasicInfo))

460 return P->SigPatchOrPrimElements;

461 return 0;

462}

#define offsetof(TYPE, MEMBER)

Analysis containing CSE Info

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

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")

static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

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.

StringRef getBuffer() const

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).

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

A table of densely packed, null-terminated strings indexed by offset.

constexpr size_t size() const

Returns the byte size of the table.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

std::string str() const

Return the twine contents as a std::string.

static Expected< DXContainer > create(MemoryBufferRef Object)

uint8_t getSigInputCount() const

uint8_t getSigPatchOrPrimCount() const

Error parse(uint16_t ShaderKind)

uint8_t getSigOutputCount() const

Error initialize(StringRef Part)

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(bool Validate, const char *Fmt, Ts &&...Vals)

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.