16 std::array<uint32_t, GT_FILTER_BYTES / 4> words{};
17 const auto at = [&words](uint32_t word) -> uint32_t& {
18 return words[word - GT_FILTER_OFFSET / 4];
21 at(GT_WORD_ENABLED) = filter.
enabled ? 1 : 0;
23 at(GT_WORD_TICK_BEGIN) =
static_cast<uint32_t
>(filter.
tickBegin);
24 at(GT_WORD_TICK_BEGIN + 1) =
static_cast<uint32_t
>(filter.
tickBegin >> 32);
25 at(GT_WORD_TICK_END) =
static_cast<uint32_t
>(filter.
tickEnd);
26 at(GT_WORD_TICK_END + 1) =
static_cast<uint32_t
>(filter.
tickEnd >> 32);
27 for (uint32_t axis = 0; axis < 3; ++axis) {
28 at(GT_WORD_BOX_MIN + axis) = filter.
boxMin[axis];
29 at(GT_WORD_BOX_MAX + axis) = filter.
boxMax[axis];
36 return {.tick = uint64_t{words[0]} | (uint64_t{words[1]} << 32),
37 .kind = words[2] >> GT_SUBJECT_BITS,
38 .subject = words[2] & GT_SUBJECT_MASK,
49 uint32_t slotCount, uint32_t capacity) {
51 const uint64_t bytes = GT_HEADER_BYTES + uint64_t{capacity} * GT_RECORD_BYTES;
56 return std::unexpected(
"連鎖のトレースを作れない: " + ring.error());
61 return std::unexpected(
"連鎖のトレースの範囲のバッファを作れない");
63 void* mapped =
nullptr;
64 const D3D12_RANGE noRead{};
65 if (FAILED(upload->Map(0, &noRead, &mapped)))
66 return std::unexpected(
"連鎖のトレースの範囲のバッファを Map できない");
68 upload->SetName(L
"GraphTrace.filter");
70 GraphTrace trace(std::move(*ring), std::move(upload),
static_cast<std::byte*
>(mapped), capacity, slotCount);
85 const auto words = FilterWords(
m_filter);
86 std::memcpy(
m_filterMapped +
size_t{slot} * GT_FILTER_BYTES, words.data(),
sizeof(words));
90 ID3D12Resource* buffer =
m_ring.Buffer();
91 const D3D12_RESOURCE_BARRIER toCopyDest =
Transition(buffer, D3D12_RESOURCE_STATE_COMMON,
92 D3D12_RESOURCE_STATE_COPY_DEST);
93 list->ResourceBarrier(1, &toCopyDest);
94 list->CopyBufferRegion(buffer, GT_FILTER_OFFSET,
m_filterUpload.Get(), uint64_t{slot} * GT_FILTER_BYTES,
97 const D3D12_RESOURCE_BARRIER toCommon =
Transition(buffer, D3D12_RESOURCE_STATE_COPY_DEST,
98 D3D12_RESOURCE_STATE_COMMON);
99 list->ResourceBarrier(1, &toCommon);
110 m_ring.RecordReadbackAndReset(list, slot, GT_HEADER_BYTES + uint64_t{capacity} * GT_RECORD_BYTES);
115 std::array<uint32_t, GT_HEADER_BYTES / 4> header{};
116 if (!
m_ring.Read(slot, std::as_writable_bytes(std::span(header))))
117 return std::unexpected(std::format(
"連鎖のトレースを読み戻せない(slot {})", slot));
119 const uint32_t requested = header[GT_WORD_REQUESTED];
120 const uint32_t written = std::min(requested,
m_slotFilters[slot].capacity);
125 std::vector<uint32_t> words((GT_HEADER_BYTES +
size_t{written} * GT_RECORD_BYTES) / 4);
126 if (!
m_ring.Read(slot, std::as_writable_bytes(std::span(words))))
127 return std::unexpected(std::format(
"連鎖のトレースの記録を読み戻せない(slot {})", slot));
129 frame.records.reserve(written);
130 for (uint32_t index = 0; index < written; ++index) {
131 const size_t first = (GT_HEADER_BYTES +
size_t{index} * GT_RECORD_BYTES) / 4;
132 frame.records.push_back(DecodeRecord(std::span(words).subspan(first).first<4>()));
GraphTraceFilter m_filter
void RecordReadbackAndReset(ID3D12GraphicsCommandList *list, uint32_t slot=0) const
void RecordBegin(ID3D12GraphicsCommandList *list, uint32_t slot=0)
void SetFilter(const GraphTraceFilter &filter)
std::byte * m_filterMapped
static std::expected< GraphTrace, std::string > Create(ID3D12Device *device, const GraphTraceFilter &filter, uint32_t slotCount=1, uint32_t capacity=0)
GraphTrace(ReadbackRing &&ring, ComPtr< ID3D12Resource > filterUpload, std::byte *filterMapped, uint32_t capacity, uint32_t slotCount)
ComPtr< ID3D12Resource > m_filterUpload
std::vector< GraphTraceFilter > m_slotFilters
std::expected< GraphTraceFrame, std::string > Read(uint32_t slot=0) const
static std::expected< ReadbackRing, std::string > Create(ID3D12Device *device, uint64_t bytes, uint64_t headerBytes, uint32_t slotCount, std::wstring_view name)
GraphTraceRecord DecodeRecord(std::span< const uint32_t, 4 > words)
std::array< uint32_t, GT_FILTER_BYTES/4 > FilterWords(const GraphTraceFilter &filter)
D3D12_RESOURCE_BARRIER Transition(ID3D12Resource *resource, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after)
ComPtr< ID3D12Resource > CreateBuffer(ID3D12Device *device, uint64_t sizeBytes, BufferKind kind)
void SortGraphTrace(std::vector< GraphTraceRecord > &records)
std::array< uint32_t, 3 > boxMax
std::array< uint32_t, 3 > boxMin