Skip to content

Commit 8a38ed2

Browse files
MarijnS95claude
andcommitted
[offloader] Fan a single DXIL library across an RT pipeline's Shaders[]
RayTracing pipelines compile every entry point — raygen, miss, closest-hit, any-hit, intersection, callable — into a single DXIL library via `dxc -T lib_6_x` / `clang-dxc -T lib_6_x`. That's the shape every real DXR app ships: D3D12's CreateStateObject requires a DXIL-library subobject anyway, and the driver fuses entry points across the whole library at link time, so writing one .hlsl file and compiling it once is both idiomatic and the path the framework's `%dxc_target_lib` substitution emits. Compute and raster pipelines stay one-to-one (the existing position- based mapping handles VS+PS, AS+MS+PS, etc.). RT pipelines today need N positional args even though one library blob holds every entry — which the foundational `raygen-roundtrip.test` runs straight into: 3 Shaders[] entries vs 1 input file fails the count check before any GPU work happens. Detect the RT-pipeline-with-one-input shape and copy the library blob into every `Shaders[].Shader` slot via `MemoryBuffer::getMemBufferCopy`. Each entry owns its own buffer copy (DXIL libraries are KBs, no real memory pressure) keeping the existing `unique_ptr<MemoryBuffer>` ownership model intact. Non-RT pipelines still go through the positional path and still enforce the count check. Verified by re-running `raygen-roundtrip.test`'s pipeline.yaml + the DXIL library via Wine + vkd3d-proton with a single .o argument — same 0xBEEF result the prior three-arg invocation produced. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e4b6b65 commit 8a38ed2

1 file changed

Lines changed: 29 additions & 9 deletions

File tree

tools/offloader/offloader.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,36 @@ static int run() {
113113
YIn >> PipelineDesc;
114114
ExitOnErr(llvm::errorCodeToError(YIn.error()));
115115

116-
// Read in the shaders
117-
for (size_t I = 0; I < InputShader.size(); ++I) {
118-
PipelineDesc.Shaders[I].Shader = readFile(InputShader[I]);
119-
}
116+
// Read in the shaders.
117+
//
118+
// RayTracing pipelines compile every entry point — raygen, miss,
119+
// closest-hit, any-hit, intersection, callable — into a single DXIL
120+
// library via `dxc -T lib_6_x` / `clang-dxc -T lib_6_x`. That's the
121+
// shape every real DXR app ships: D3D12's CreateStateObject requires a
122+
// DXIL-library subobject anyway, and the driver fuses entry points
123+
// across the whole library at link time. So when an RT pipeline is
124+
// paired with a single input file, fan that one blob across every
125+
// Shaders[] entry rather than asking the test author to duplicate the
126+
// path N times on the offloader command line.
127+
if (PipelineDesc.isRayTracing() && InputShader.size() == 1 &&
128+
PipelineDesc.Shaders.size() > 1) {
129+
std::unique_ptr<MemoryBuffer> Lib = readFile(InputShader[0]);
130+
const StringRef LibBytes = Lib->getBuffer();
131+
const StringRef LibName = Lib->getBufferIdentifier();
132+
for (size_t I = 0; I < PipelineDesc.Shaders.size(); ++I)
133+
PipelineDesc.Shaders[I].Shader =
134+
MemoryBuffer::getMemBufferCopy(LibBytes, LibName);
135+
} else {
136+
for (size_t I = 0; I < InputShader.size(); ++I) {
137+
PipelineDesc.Shaders[I].Shader = readFile(InputShader[I]);
138+
}
120139

121-
if (InputShader.size() != PipelineDesc.Shaders.size())
122-
ExitOnErr(createStringError(
123-
std::errc::invalid_argument,
124-
"Pipeline description expects %d shader(s) %d provided",
125-
PipelineDesc.Shaders.size(), InputShader.size()));
140+
if (InputShader.size() != PipelineDesc.Shaders.size())
141+
ExitOnErr(createStringError(
142+
std::errc::invalid_argument,
143+
"Pipeline description expects %d shader(s) %d provided",
144+
PipelineDesc.Shaders.size(), InputShader.size()));
145+
}
126146

127147
// Try to guess the API by reading the shader binary.
128148
const StringRef Binary = PipelineDesc.Shaders[0].Shader->getBuffer();

0 commit comments

Comments
 (0)