PIX: DxcPixDxilInstructionOffsets should operate on libs (#5046)

This commit is contained in:
Jeff Noyle 2023-02-22 10:19:07 -08:00 коммит произвёл GitHub
Родитель 740dd0951b
Коммит 67162b4d17
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 199 добавлений и 19 удалений

Просмотреть файл

@ -9,12 +9,15 @@
// // // //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include "dxc/DXIL/DxilOperations.h"
#include "dxc/Support/WinIncludes.h" #include "dxc/Support/WinIncludes.h"
#include "dxc/Support/exception.h" #include "dxc/Support/exception.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Module.h"
#include "DxcPixLiveVariables.h" #include "DxcPixLiveVariables.h"
#include "DxcPixDxilDebugInfo.h" #include "DxcPixDxilDebugInfo.h"
@ -172,24 +175,25 @@ dxil_debug_info::DxcPixDxilInstructionOffsets::DxcPixDxilInstructionOffsets(
{ {
assert(SourceColumn == 0); assert(SourceColumn == 0);
(void)SourceColumn; (void)SourceColumn;
auto Fn = pSession->DxilModuleRef().GetEntryFunction(); for (llvm::Function &Fn :
auto &Blocks = Fn->getBasicBlockList(); pSession->DxilModuleRef().GetModule()->functions()) {
for (auto& CurrentBlock : Blocks) { if (Fn.isDeclaration() || Fn.isIntrinsic() || hlsl::OP::IsDxilOpFunc(&Fn))
auto& Is = CurrentBlock.getInstList(); continue;
for (auto& Inst : Is) { auto &Blocks = Fn.getBasicBlockList();
auto & debugLoc = Inst.getDebugLoc(); for (auto &CurrentBlock : Blocks) {
if (debugLoc) auto &Is = CurrentBlock.getInstList();
{ for (auto &Inst : Is) {
unsigned line = debugLoc.getLine(); auto &debugLoc = Inst.getDebugLoc();
if (line == SourceLine) if (debugLoc) {
{ unsigned line = debugLoc.getLine();
auto file = debugLoc.get()->getFilename(); if (line == SourceLine) {
if (CompareFilenames(FileName, file.str().c_str())) auto file = debugLoc.get()->getFilename();
{ if (CompareFilenames(FileName, file.str().c_str())) {
std::uint32_t InstructionNumber; std::uint32_t InstructionNumber;
if (pix_dxil::PixDxilInstNum::FromInst(&Inst, &InstructionNumber)) if (pix_dxil::PixDxilInstNum::FromInst(&Inst,
{ &InstructionNumber)) {
m_offsets.push_back(InstructionNumber); m_offsets.push_back(InstructionNumber);
}
} }
} }
} }

Просмотреть файл

@ -229,6 +229,8 @@ public:
TEST_METHOD(PixTypeManager_SamplersAndResources) TEST_METHOD(PixTypeManager_SamplersAndResources)
TEST_METHOD(PixTypeManager_XBoxDiaAssert) TEST_METHOD(PixTypeManager_XBoxDiaAssert)
TEST_METHOD(DxcPixDxilDebugInfo_InstructionOffsets)
TEST_METHOD(VirtualRegisters_InstructionCounts) TEST_METHOD(VirtualRegisters_InstructionCounts)
TEST_METHOD(VirtualRegisters_AlignedOffsets) TEST_METHOD(VirtualRegisters_AlignedOffsets)
@ -1803,6 +1805,8 @@ TEST_F(PixTest, PixDebugCompileInfo) {
VERIFY_ARE_EQUAL(std::wstring(profile), std::wstring(hlslTarget)); VERIFY_ARE_EQUAL(std::wstring(profile), std::wstring(hlslTarget));
} }
static LPCWSTR defaultFilename = L"source.hlsl";
static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText, static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
LPWSTR pTargetProfile, std::vector<LPCWSTR> &args, LPWSTR pTargetProfile, std::vector<LPCWSTR> &args,
_Outptr_ IDxcBlob **ppResult) { _Outptr_ IDxcBlob **ppResult) {
@ -1813,7 +1817,7 @@ static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
*ppResult = nullptr; *ppResult = nullptr;
VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler)); VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
Utf8ToBlob(dllSupport, pText, &pSource); Utf8ToBlob(dllSupport, pText, &pSource);
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main", VERIFY_SUCCEEDED(pCompiler->Compile(pSource, defaultFilename, L"main",
pTargetProfile, args.data(), args.size(), pTargetProfile, args.data(), args.size(),
nullptr, 0, nullptr, &pResult)); nullptr, 0, nullptr, &pResult));
@ -2143,6 +2147,178 @@ VSOut main( const uint id : SV_OutputControlPointID,
VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession));
} }
std::vector<std::string> SplitAndPreserveEmptyLines(std::string const & str, char delimeter) {
std::vector<std::string> lines;
auto const *p = str.data();
auto const *justPastPreviousDelimiter = p;
while (p < str.data() + str.length()) {
if (*p == delimeter) {
lines.emplace_back(justPastPreviousDelimiter, p - justPastPreviousDelimiter);
justPastPreviousDelimiter = p + 1;
p = justPastPreviousDelimiter;
} else {
p++;
}
}
lines.emplace_back(std::string(justPastPreviousDelimiter,
p - justPastPreviousDelimiter));
return lines;
}
TEST_F(PixTest, DxcPixDxilDebugInfo_InstructionOffsets) {
if (m_ver.SkipDxilVersion(1, 5))
return;
const char *hlsl = R"(RaytracingAccelerationStructure Scene : register(t0, space0);
RWTexture2D<float4> RenderTarget : register(u0);
struct SceneConstantBuffer
{
float4x4 projectionToWorld;
float4 cameraPosition;
float4 lightPosition;
float4 lightAmbientColor;
float4 lightDiffuseColor;
};
ConstantBuffer<SceneConstantBuffer> g_sceneCB : register(b0);
struct RayPayload
{
float4 color;
};
inline void GenerateCameraRay(uint2 index, out float3 origin, out float3 direction)
{
float2 xy = index + 0.5f; // center in the middle of the pixel.
float2 screenPos = xy;// / DispatchRaysDimensions().xy * 2.0 - 1.0;
// Invert Y for DirectX-style coordinates.
screenPos.y = -screenPos.y;
// Unproject the pixel coordinate into a ray.
float4 world = /*mul(*/float4(screenPos, 0, 1)/*, g_sceneCB.projectionToWorld)*/;
//world.xyz /= world.w;
origin = world.xyz; //g_sceneCB.cameraPosition.xyz;
direction = float3(1,0,0);//normalize(world.xyz - origin);
}
void RaygenCommon()
{
float3 rayDir;
float3 origin;
// Generate a ray for a camera pixel corresponding to an index from the dispatched 2D grid.
GenerateCameraRay(DispatchRaysIndex().xy, origin, rayDir);
// Trace the ray.
// Set the ray's extents.
RayDesc ray;
ray.Origin = origin;
ray.Direction = rayDir;
// Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors.
// TMin should be kept small to prevent missing geometry at close contact areas.
ray.TMin = 0.001;
ray.TMax = 10000.0;
RayPayload payload = { float4(0, 0, 0, 0) };
TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);
// Write the raytraced color to the output texture.
// RenderTarget[DispatchRaysIndex().xy] = payload.color;
}
[shader("raygeneration")]
void Raygen()
{
RaygenCommon();
}
typedef BuiltInTriangleIntersectionAttributes MyAttributes;
[shader("closesthit")]
void InnerClosestHitShader(inout RayPayload payload, in MyAttributes attr)
{
payload.color = float4(0,1,0,0);
}
[shader("miss")]
void MyMissShader(inout RayPayload payload)
{
payload.color = float4(1, 0, 0, 0);
})";
auto lines = SplitAndPreserveEmptyLines(std::string(hlsl), '\n');
DWORD countOfSourceLines = static_cast<DWORD>(lines.size());
CComPtr<IDiaDataSource> pDiaDataSource;
CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6",
&pDiaDataSource);
CComPtr<IDiaSession> session;
VERIFY_SUCCEEDED(pDiaDataSource->openSession(&session));
CComPtr<IDxcPixDxilDebugInfoFactory> Factory;
VERIFY_SUCCEEDED(session->QueryInterface(IID_PPV_ARGS(&Factory)));
CComPtr<IDxcPixDxilDebugInfo> dxilDebugger;
VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger));
// Quick crash test for wrong filename:
CComPtr<IDxcPixDxilInstructionOffsets> garbageOffsets;
dxilDebugger->InstructionOffsetsFromSourceLocation(L"garbage", 0, 0,
&garbageOffsets);
// Since the API offers both source-from-instruction and
// instruction-from-source, we'll compare them against each other:
for (size_t line = 0; line < lines.size(); ++line) {
auto lineNumber = static_cast<DWORD>(line);
constexpr DWORD sourceLocationReaderOnlySupportsColumnZero = 0;
CComPtr<IDxcPixDxilInstructionOffsets> offsets;
dxilDebugger->InstructionOffsetsFromSourceLocation(
defaultFilename, lineNumber, sourceLocationReaderOnlySupportsColumnZero,
&offsets);
auto offsetCount = offsets->GetCount();
for (DWORD offsetOrdinal = 0; offsetOrdinal < offsetCount;
++offsetOrdinal) {
DWORD instructionOffsetFromSource =
offsets->GetOffsetByIndex(offsetOrdinal);
CComPtr<IDxcPixDxilSourceLocations> sourceLocations;
VERIFY_SUCCEEDED(dxilDebugger->SourceLocationsFromInstructionOffset(
instructionOffsetFromSource, &sourceLocations));
auto count = sourceLocations->GetCount();
for (DWORD sourceLocationOrdinal = 0; sourceLocationOrdinal < count;
++sourceLocationOrdinal) {
DWORD lineNumber =
sourceLocations->GetLineNumberByIndex(sourceLocationOrdinal);
DWORD column = sourceLocations->GetColumnByIndex(sourceLocationOrdinal);
CComBSTR filename;
VERIFY_SUCCEEDED(sourceLocations->GetFileNameByIndex(
sourceLocationOrdinal, &filename));
VERIFY_IS_TRUE(lineNumber < countOfSourceLines);
constexpr DWORD lineNumbersAndColumnsStartAtOne = 1;
VERIFY_IS_TRUE(
column - lineNumbersAndColumnsStartAtOne <=
static_cast<DWORD>(lines.at(lineNumber - lineNumbersAndColumnsStartAtOne).size()));
VERIFY_IS_TRUE(0 == wcscmp(filename, defaultFilename));
}
}
}
}
CComPtr<IDxcBlob> PixTest::RunShaderAccessTrackingPass(IDxcBlob *blob) { CComPtr<IDxcBlob> PixTest::RunShaderAccessTrackingPass(IDxcBlob *blob) {
CComPtr<IDxcOptimizer> pOptimizer; CComPtr<IDxcOptimizer> pOptimizer;
VERIFY_SUCCEEDED( VERIFY_SUCCEEDED(