Skip to content

Commit 8f4d1f4

Browse files
jeffnnGreg Roth
authored andcommitted
PIX: DxcPixDxilInstructionOffsets should operate on libs (#5046)
(cherry picked from commit 67162b4)
1 parent 0795b94 commit 8f4d1f4

2 files changed

Lines changed: 199 additions & 19 deletions

File tree

lib/DxilDia/DxcPixDxilDebugInfo.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99
// //
1010
///////////////////////////////////////////////////////////////////////////////
1111

12+
#include "dxc/DXIL/DxilOperations.h"
13+
1214
#include "dxc/Support/WinIncludes.h"
1315

1416
#include "dxc/Support/exception.h"
1517
#include "llvm/IR/Instructions.h"
1618
#include "llvm/IR/DebugInfo.h"
1719
#include "llvm/IR/DebugInfoMetadata.h"
20+
#include "llvm/IR/Module.h"
1821

1922
#include "DxcPixLiveVariables.h"
2023
#include "DxcPixDxilDebugInfo.h"
@@ -172,24 +175,25 @@ dxil_debug_info::DxcPixDxilInstructionOffsets::DxcPixDxilInstructionOffsets(
172175
{
173176
assert(SourceColumn == 0);
174177
(void)SourceColumn;
175-
auto Fn = pSession->DxilModuleRef().GetEntryFunction();
176-
auto &Blocks = Fn->getBasicBlockList();
177-
for (auto& CurrentBlock : Blocks) {
178-
auto& Is = CurrentBlock.getInstList();
179-
for (auto& Inst : Is) {
180-
auto & debugLoc = Inst.getDebugLoc();
181-
if (debugLoc)
182-
{
183-
unsigned line = debugLoc.getLine();
184-
if (line == SourceLine)
185-
{
186-
auto file = debugLoc.get()->getFilename();
187-
if (CompareFilenames(FileName, file.str().c_str()))
188-
{
189-
std::uint32_t InstructionNumber;
190-
if (pix_dxil::PixDxilInstNum::FromInst(&Inst, &InstructionNumber))
191-
{
192-
m_offsets.push_back(InstructionNumber);
178+
for (llvm::Function &Fn :
179+
pSession->DxilModuleRef().GetModule()->functions()) {
180+
if (Fn.isDeclaration() || Fn.isIntrinsic() || hlsl::OP::IsDxilOpFunc(&Fn))
181+
continue;
182+
auto &Blocks = Fn.getBasicBlockList();
183+
for (auto &CurrentBlock : Blocks) {
184+
auto &Is = CurrentBlock.getInstList();
185+
for (auto &Inst : Is) {
186+
auto &debugLoc = Inst.getDebugLoc();
187+
if (debugLoc) {
188+
unsigned line = debugLoc.getLine();
189+
if (line == SourceLine) {
190+
auto file = debugLoc.get()->getFilename();
191+
if (CompareFilenames(FileName, file.str().c_str())) {
192+
std::uint32_t InstructionNumber;
193+
if (pix_dxil::PixDxilInstNum::FromInst(&Inst,
194+
&InstructionNumber)) {
195+
m_offsets.push_back(InstructionNumber);
196+
}
193197
}
194198
}
195199
}

tools/clang/unittests/HLSL/PixTest.cpp

Lines changed: 177 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ class PixTest {
229229
TEST_METHOD(PixTypeManager_SamplersAndResources)
230230
TEST_METHOD(PixTypeManager_XBoxDiaAssert)
231231

232+
TEST_METHOD(DxcPixDxilDebugInfo_InstructionOffsets)
233+
232234
TEST_METHOD(VirtualRegisters_InstructionCounts)
233235
TEST_METHOD(VirtualRegisters_AlignedOffsets)
234236

@@ -1803,6 +1805,8 @@ TEST_F(PixTest, PixDebugCompileInfo) {
18031805
VERIFY_ARE_EQUAL(std::wstring(profile), std::wstring(hlslTarget));
18041806
}
18051807

1808+
static LPCWSTR defaultFilename = L"source.hlsl";
1809+
18061810
static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
18071811
LPWSTR pTargetProfile, std::vector<LPCWSTR> &args,
18081812
_Outptr_ IDxcBlob **ppResult) {
@@ -1813,7 +1817,7 @@ static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
18131817
*ppResult = nullptr;
18141818
VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
18151819
Utf8ToBlob(dllSupport, pText, &pSource);
1816-
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main",
1820+
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, defaultFilename, L"main",
18171821
pTargetProfile, args.data(), args.size(),
18181822
nullptr, 0, nullptr, &pResult));
18191823

@@ -2143,6 +2147,178 @@ VSOut main( const uint id : SV_OutputControlPointID,
21432147
VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession));
21442148
}
21452149

2150+
std::vector<std::string> SplitAndPreserveEmptyLines(std::string const & str, char delimeter) {
2151+
std::vector<std::string> lines;
2152+
2153+
auto const *p = str.data();
2154+
auto const *justPastPreviousDelimiter = p;
2155+
while (p < str.data() + str.length()) {
2156+
if (*p == delimeter) {
2157+
lines.emplace_back(justPastPreviousDelimiter, p - justPastPreviousDelimiter);
2158+
justPastPreviousDelimiter = p + 1;
2159+
p = justPastPreviousDelimiter;
2160+
} else {
2161+
p++;
2162+
}
2163+
}
2164+
2165+
lines.emplace_back(std::string(justPastPreviousDelimiter,
2166+
p - justPastPreviousDelimiter));
2167+
2168+
return lines;
2169+
}
2170+
2171+
TEST_F(PixTest, DxcPixDxilDebugInfo_InstructionOffsets) {
2172+
2173+
if (m_ver.SkipDxilVersion(1, 5))
2174+
return;
2175+
2176+
const char *hlsl = R"(RaytracingAccelerationStructure Scene : register(t0, space0);
2177+
RWTexture2D<float4> RenderTarget : register(u0);
2178+
2179+
struct SceneConstantBuffer
2180+
{
2181+
float4x4 projectionToWorld;
2182+
float4 cameraPosition;
2183+
float4 lightPosition;
2184+
float4 lightAmbientColor;
2185+
float4 lightDiffuseColor;
2186+
};
2187+
2188+
ConstantBuffer<SceneConstantBuffer> g_sceneCB : register(b0);
2189+
2190+
struct RayPayload
2191+
{
2192+
float4 color;
2193+
};
2194+
2195+
inline void GenerateCameraRay(uint2 index, out float3 origin, out float3 direction)
2196+
{
2197+
float2 xy = index + 0.5f; // center in the middle of the pixel.
2198+
float2 screenPos = xy;// / DispatchRaysDimensions().xy * 2.0 - 1.0;
2199+
2200+
// Invert Y for DirectX-style coordinates.
2201+
screenPos.y = -screenPos.y;
2202+
2203+
// Unproject the pixel coordinate into a ray.
2204+
float4 world = /*mul(*/float4(screenPos, 0, 1)/*, g_sceneCB.projectionToWorld)*/;
2205+
2206+
//world.xyz /= world.w;
2207+
origin = world.xyz; //g_sceneCB.cameraPosition.xyz;
2208+
direction = float3(1,0,0);//normalize(world.xyz - origin);
2209+
}
2210+
2211+
void RaygenCommon()
2212+
{
2213+
float3 rayDir;
2214+
float3 origin;
2215+
2216+
// Generate a ray for a camera pixel corresponding to an index from the dispatched 2D grid.
2217+
GenerateCameraRay(DispatchRaysIndex().xy, origin, rayDir);
2218+
2219+
// Trace the ray.
2220+
// Set the ray's extents.
2221+
RayDesc ray;
2222+
ray.Origin = origin;
2223+
ray.Direction = rayDir;
2224+
// Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors.
2225+
// TMin should be kept small to prevent missing geometry at close contact areas.
2226+
ray.TMin = 0.001;
2227+
ray.TMax = 10000.0;
2228+
RayPayload payload = { float4(0, 0, 0, 0) };
2229+
TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);
2230+
2231+
// Write the raytraced color to the output texture.
2232+
// RenderTarget[DispatchRaysIndex().xy] = payload.color;
2233+
}
2234+
2235+
[shader("raygeneration")]
2236+
void Raygen()
2237+
{
2238+
RaygenCommon();
2239+
}
2240+
2241+
typedef BuiltInTriangleIntersectionAttributes MyAttributes;
2242+
2243+
[shader("closesthit")]
2244+
void InnerClosestHitShader(inout RayPayload payload, in MyAttributes attr)
2245+
{
2246+
payload.color = float4(0,1,0,0);
2247+
}
2248+
2249+
2250+
[shader("miss")]
2251+
void MyMissShader(inout RayPayload payload)
2252+
{
2253+
payload.color = float4(1, 0, 0, 0);
2254+
})";
2255+
2256+
auto lines = SplitAndPreserveEmptyLines(std::string(hlsl), '\n');
2257+
DWORD countOfSourceLines = static_cast<DWORD>(lines.size());
2258+
2259+
CComPtr<IDiaDataSource> pDiaDataSource;
2260+
CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6",
2261+
&pDiaDataSource);
2262+
2263+
CComPtr<IDiaSession> session;
2264+
VERIFY_SUCCEEDED(pDiaDataSource->openSession(&session));
2265+
2266+
CComPtr<IDxcPixDxilDebugInfoFactory> Factory;
2267+
VERIFY_SUCCEEDED(session->QueryInterface(IID_PPV_ARGS(&Factory)));
2268+
2269+
CComPtr<IDxcPixDxilDebugInfo> dxilDebugger;
2270+
VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger));
2271+
2272+
// Quick crash test for wrong filename:
2273+
CComPtr<IDxcPixDxilInstructionOffsets> garbageOffsets;
2274+
dxilDebugger->InstructionOffsetsFromSourceLocation(L"garbage", 0, 0,
2275+
&garbageOffsets);
2276+
2277+
// Since the API offers both source-from-instruction and
2278+
// instruction-from-source, we'll compare them against each other:
2279+
for (size_t line = 0; line < lines.size(); ++line) {
2280+
2281+
auto lineNumber = static_cast<DWORD>(line);
2282+
2283+
constexpr DWORD sourceLocationReaderOnlySupportsColumnZero = 0;
2284+
CComPtr<IDxcPixDxilInstructionOffsets> offsets;
2285+
dxilDebugger->InstructionOffsetsFromSourceLocation(
2286+
defaultFilename, lineNumber, sourceLocationReaderOnlySupportsColumnZero,
2287+
&offsets);
2288+
2289+
auto offsetCount = offsets->GetCount();
2290+
for (DWORD offsetOrdinal = 0; offsetOrdinal < offsetCount;
2291+
++offsetOrdinal) {
2292+
2293+
DWORD instructionOffsetFromSource =
2294+
offsets->GetOffsetByIndex(offsetOrdinal);
2295+
2296+
CComPtr<IDxcPixDxilSourceLocations> sourceLocations;
2297+
VERIFY_SUCCEEDED(dxilDebugger->SourceLocationsFromInstructionOffset(
2298+
instructionOffsetFromSource, &sourceLocations));
2299+
2300+
auto count = sourceLocations->GetCount();
2301+
for (DWORD sourceLocationOrdinal = 0; sourceLocationOrdinal < count;
2302+
++sourceLocationOrdinal) {
2303+
DWORD lineNumber =
2304+
sourceLocations->GetLineNumberByIndex(sourceLocationOrdinal);
2305+
DWORD column = sourceLocations->GetColumnByIndex(sourceLocationOrdinal);
2306+
CComBSTR filename;
2307+
VERIFY_SUCCEEDED(sourceLocations->GetFileNameByIndex(
2308+
sourceLocationOrdinal, &filename));
2309+
2310+
VERIFY_IS_TRUE(lineNumber < countOfSourceLines);
2311+
2312+
constexpr DWORD lineNumbersAndColumnsStartAtOne = 1;
2313+
VERIFY_IS_TRUE(
2314+
column - lineNumbersAndColumnsStartAtOne <=
2315+
static_cast<DWORD>(lines.at(lineNumber - lineNumbersAndColumnsStartAtOne).size()));
2316+
VERIFY_IS_TRUE(0 == wcscmp(filename, defaultFilename));
2317+
}
2318+
}
2319+
}
2320+
}
2321+
21462322
CComPtr<IDxcBlob> PixTest::RunShaderAccessTrackingPass(IDxcBlob *blob) {
21472323
CComPtr<IDxcOptimizer> pOptimizer;
21482324
VERIFY_SUCCEEDED(

0 commit comments

Comments
 (0)