Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/include/llvm/Object/DXContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,8 @@ class LLVM_ABI DXContainerObjectFile : public ObjectFile {
}

public:
const DXContainer &getDXContainer() const { return Container; }

static bool classof(const Binary *v) { return v->isDXContainer(); }

Expected<StringRef> getSymbolName(DataRefImpl) const override;
Expand Down
161 changes: 161 additions & 0 deletions llvm/test/tools/llvm-objdump/DXContainer/input-output-signatures.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# RUN: yaml2obj %s -o %t
# RUN: llvm-objdump -p %t | FileCheck %s
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits/suggestions:

  1. I'd add a blank line between the RUN and YAML lines.
  2. I'd add a brief comment at the start of the test describing the feature being tested.
  3. I'd add --match-full-lines and --strict-whitespace to the FileCheck command, to ensure the formatting matches the expected.

--- !dxcontainer
Header:
Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
Version:
Major: 1
Minor: 0
FileSize: 630
PartCount: 3
PartOffsets: [ 64, 124, 184 ]
Parts:
- Name: ISG1
Size: 52
Signature:
Parameters:
- Stream: 0
Name: AAA_HSFoo
Index: 4391238 # This value forces the index column to widen
SystemValue: Undefined
CompType: Float32
Register: 0
Mask: 7
ExclusiveMask: 2
MinPrecision: Default
- Name: OSG1
Size: 52
Signature:
Parameters:
- Stream: 0
Name: SV_Position
Index: 0
SystemValue: Position
CompType: Float32
Register: 2147483647 # This value forces the register column to widen
Mask: 15
ExclusiveMask: 0
MinPrecision: Default
- Name: PSG1
Size: 402
Signature:
Parameters:
- Stream: 0
Name: SV_TessFactor
Index: 0
SystemValue: FinalQuadEdgeTessfactor # The tessfactor forces the SysVal column to widen
CompType: Float32
Register: 0
Mask: 8
ExclusiveMask: 8
MinPrecision: Default
- Stream: 0
Name: BBB
Index: 0
SystemValue: Undefined
CompType: Float32
Register: 0
Mask: 7
ExclusiveMask: 0
MinPrecision: Default
- Stream: 0
Name: SV_TessFactor
Index: 1
SystemValue: FinalQuadEdgeTessfactor
CompType: Float32
Register: 1
Mask: 8
ExclusiveMask: 8
MinPrecision: Default
- Stream: 0
Name: BBB
Index: 1
SystemValue: Undefined
CompType: Float32
Register: 1
Mask: 7
ExclusiveMask: 0
MinPrecision: Default
- Stream: 0
Name: SV_TessFactor
Index: 2
SystemValue: FinalQuadEdgeTessfactor
CompType: Float32
Register: 2
Mask: 8
ExclusiveMask: 8
MinPrecision: Default
- Stream: 0
Name: BBB
Index: 2
SystemValue: Undefined
CompType: Float32
Register: 2
Mask: 7
ExclusiveMask: 0
MinPrecision: Default
- Stream: 0
Name: SV_TessFactor
Index: 3
SystemValue: FinalQuadEdgeTessfactor
CompType: Float32
Register: 3
Mask: 8
ExclusiveMask: 8
MinPrecision: Default
- Stream: 0
Name: SV_InsideTessFactor
Index: 0
SystemValue: FinalQuadInsideTessfactor
CompType: Float32
Register: 4
Mask: 8
ExclusiveMask: 0
MinPrecision: Default
- Stream: 0
Name: SV_InsideTessFactor
Index: 1
SystemValue: FinalQuadInsideTessfactor
CompType: Float32
Register: 5
Mask: 8
ExclusiveMask: 0
MinPrecision: Default
- Stream: 0
Name: AVeryLongStringThatWillForceWidening # This value forces name column to widen
Index: 0
SystemValue: Undefined
CompType: Float32
Register: 6
Mask: 15
ExclusiveMask: 4
MinPrecision: Default
...

# CHECK: ; Input signature:
# CHECK-NEXT: ;
# CHECK-NEXT: ; Name Index Mask Register SysValue Format Used
# CHECK-NEXT: ; ------------------------ ------- ----- -------- ---------- ------- -----
# CHECK-NEXT: ; AAA_HSFoo 4391238 xyz 0 Undefined Float32 y

# CHECK: ; Output signature:
# CHECK-NEXT: ;
# CHECK-NEXT: ; Name Index Mask Register SysValue Format Used
# CHECK-NEXT: ; ------------------------ ----- ----- ---------- ---------- ------- -----
# CHECK-NEXT: ; SV_Position 0 xyzw 2147483647 Position Float32

# CHECK: ; Patch Constant signature:
# CHECK-NEXT: ;
# CHECK-NEXT: ; Name Index Mask Register SysValue Format Used
# CHECK-NEXT: ; ------------------------------------ ----- ----- -------- ------------------------- ------- -----
# CHECK-NEXT: ; SV_TessFactor 0 w 0 FinalQuadEdgeTessfactor Float32 w
# CHECK-NEXT: ; BBB 0 xyz 0 Undefined Float32
# CHECK-NEXT: ; SV_TessFactor 1 w 1 FinalQuadEdgeTessfactor Float32 w
# CHECK-NEXT: ; BBB 1 xyz 1 Undefined Float32
# CHECK-NEXT: ; SV_TessFactor 2 w 2 FinalQuadEdgeTessfactor Float32 w
# CHECK-NEXT: ; BBB 2 xyz 2 Undefined Float32
# CHECK-NEXT: ; SV_TessFactor 3 w 3 FinalQuadEdgeTessfactor Float32 w
# CHECK-NEXT: ; SV_InsideTessFactor 0 w 4 FinalQuadInsideTessfactor Float32
# CHECK-NEXT: ; SV_InsideTessFactor 1 w 5 FinalQuadInsideTessfactor Float32
# CHECK-NEXT: ; AVeryLongStringThatWillForceWidening 0 xyzw 6 Undefined Float32 z
130 changes: 128 additions & 2 deletions llvm/tools/llvm-objdump/DXContainerDump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,142 @@
//===----------------------------------------------------------------------===//

#include "llvm-objdump.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/DXContainer.h"
#include "llvm/Support/ScopedPrinter.h"

using namespace llvm;
using namespace llvm::object;

static llvm::SmallString<4> maskToString(uint8_t Mask) {
llvm::SmallString<4> Result(" ");
if (Mask & 1)
Result[0] = 'x';
if (Mask & 2)
Result[1] = 'y';
if (Mask & 4)
Result[2] = 'z';
if (Mask & 8)
Result[3] = 'w';
return Result;
}

static void printColumnHeader(raw_ostream &OS, size_t Length) {
for (size_t I = 0; I < Length; ++I)
OS << "-";
}

static void printColumnHeaders(raw_ostream &OS, ArrayRef<size_t> Lengths) {
for (auto L : Lengths) {
printColumnHeader(OS, L);
OS << " ";
}
OS << "\n";
}

static size_t digitsForNumber(size_t N) {
return static_cast<size_t>(log10(static_cast<double>(N))) + 1;
}

namespace {
class DXContainerDumper : public objdump::Dumper {
const DXContainerObjectFile &Obj;

public:
DXContainerDumper(const object::DXContainerObjectFile &Obj)
: objdump::Dumper(Obj) {}
DXContainerDumper(const DXContainerObjectFile &O)
: objdump::Dumper(O), Obj(O) {}

void printPrivateHeaders() override;
void printSignature(const DirectX::Signature &S);
};

void DXContainerDumper::printSignature(const DirectX::Signature &S) {
// DXC prints a table like this as part of the shader disassembly:
//; Name Index Mask Register SysValue Format Used
//; -------------------- ----- ------ -------- -------- ------- ------
//; NORMAL 0 xyz 0 NONE float xyz
//; TEXCOORD 0 xy 1 NONE float xy

// DXC's implementation doesn't scale columns entirely completely for the
// provided input, so this implementation is a bit more complicated in
// formatting logic to scale with the size of the printed text.

// DXC gives names 21 characters for some unknown reason, I arbitrarily chose
// to start at 24 so that we're not going shorter but are using a round
// number.
size_t LongestName = 24;
size_t LongestSV = 10;
size_t LongestIndex = strlen("Index");
size_t LongestRegister = strlen("Register");
size_t LongestFormat = strlen("Format");
const size_t MaskWidth = 5;
// Compute the column widths. Skip calculating the "Mask" and "Used" columns
// since they both have widths of 4.
for (auto El : S) {
LongestName = std::max(LongestName, S.getName(El.NameOffset).size());
LongestSV = std::max(
LongestSV,
enumToStringRef(El.SystemValue, dxbc::getD3DSystemValues()).size());
LongestIndex = std::max(LongestIndex, digitsForNumber(El.Index));
LongestRegister = std::max(LongestRegister, digitsForNumber(El.Register));
LongestFormat = std::max(
LongestFormat,
enumToStringRef(El.CompType, dxbc::getSigComponentTypes()).size());
}

// Print Column headers
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Print Column headers
// Print Column headers.

OS << "; ";
OS << left_justify("Name", LongestName) << " ";
OS << right_justify("Index", LongestIndex) << " ";
OS << right_justify("Mask", MaskWidth) << " ";
OS << right_justify("Register", LongestRegister) << " ";
OS << right_justify("SysValue", LongestSV) << " ";
OS << right_justify("Format", LongestFormat) << " ";
OS << right_justify("Used", MaskWidth) << "\n";
OS << "; ";
printColumnHeaders(OS, {LongestName, LongestIndex, MaskWidth, LongestRegister,
LongestSV, LongestFormat, MaskWidth});

for (auto El : S) {
OS << "; " << left_justify(S.getName(El.NameOffset), LongestName) << " ";
OS << right_justify(std::to_string(El.Index), LongestIndex) << " ";
OS << right_justify(maskToString(El.Mask), MaskWidth) << " ";
OS << right_justify(std::to_string(El.Register), LongestRegister) << " ";
OS << right_justify(
enumToStringRef(El.SystemValue, dxbc::getD3DSystemValues()),
LongestSV)
<< " ";
OS << right_justify(
enumToStringRef(El.CompType, dxbc::getSigComponentTypes()),
LongestFormat)
<< " ";
OS << right_justify(maskToString(El.ExclusiveMask), MaskWidth) << "\n";
}
}

void DXContainerDumper::printPrivateHeaders() {
const DXContainer &C =
cast<object::DXContainerObjectFile>(Obj).getDXContainer();

if (!C.getInputSignature().isEmpty()) {
OS << "; Input signature:\n;\n";
printSignature(C.getInputSignature());
OS << ";\n";
}

if (!C.getOutputSignature().isEmpty()) {
OS << "; Output signature:\n;\n";
printSignature(C.getOutputSignature());
OS << ";\n";
}

if (!C.getPatchConstantSignature().isEmpty()) {
OS << "; Patch Constant signature:\n;\n";
printSignature(C.getPatchConstantSignature());
OS << ";\n";
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the namespace starts with no blank lines after the opening brace, but finishes with one before the closing one. I don't think the coding standards have a stated preferred style, but mismatching seems wrong regardless!

} // namespace

std::unique_ptr<objdump::Dumper> llvm::objdump::createDXContainerDumper(
Expand Down
Loading