PIX: DxcPixDxilInstructionOffsets should operate on libs (#5046)
This commit is contained in:
Родитель
740dd0951b
Коммит
67162b4d17
|
@ -9,12 +9,15 @@
|
|||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dxc/DXIL/DxilOperations.h"
|
||||
|
||||
#include "dxc/Support/WinIncludes.h"
|
||||
|
||||
#include "dxc/Support/exception.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
||||
#include "DxcPixLiveVariables.h"
|
||||
#include "DxcPixDxilDebugInfo.h"
|
||||
|
@ -172,24 +175,25 @@ dxil_debug_info::DxcPixDxilInstructionOffsets::DxcPixDxilInstructionOffsets(
|
|||
{
|
||||
assert(SourceColumn == 0);
|
||||
(void)SourceColumn;
|
||||
auto Fn = pSession->DxilModuleRef().GetEntryFunction();
|
||||
auto &Blocks = Fn->getBasicBlockList();
|
||||
for (auto& CurrentBlock : Blocks) {
|
||||
auto& Is = CurrentBlock.getInstList();
|
||||
for (auto& Inst : Is) {
|
||||
auto & debugLoc = Inst.getDebugLoc();
|
||||
if (debugLoc)
|
||||
{
|
||||
unsigned line = debugLoc.getLine();
|
||||
if (line == SourceLine)
|
||||
{
|
||||
auto file = debugLoc.get()->getFilename();
|
||||
if (CompareFilenames(FileName, file.str().c_str()))
|
||||
{
|
||||
std::uint32_t InstructionNumber;
|
||||
if (pix_dxil::PixDxilInstNum::FromInst(&Inst, &InstructionNumber))
|
||||
{
|
||||
m_offsets.push_back(InstructionNumber);
|
||||
for (llvm::Function &Fn :
|
||||
pSession->DxilModuleRef().GetModule()->functions()) {
|
||||
if (Fn.isDeclaration() || Fn.isIntrinsic() || hlsl::OP::IsDxilOpFunc(&Fn))
|
||||
continue;
|
||||
auto &Blocks = Fn.getBasicBlockList();
|
||||
for (auto &CurrentBlock : Blocks) {
|
||||
auto &Is = CurrentBlock.getInstList();
|
||||
for (auto &Inst : Is) {
|
||||
auto &debugLoc = Inst.getDebugLoc();
|
||||
if (debugLoc) {
|
||||
unsigned line = debugLoc.getLine();
|
||||
if (line == SourceLine) {
|
||||
auto file = debugLoc.get()->getFilename();
|
||||
if (CompareFilenames(FileName, file.str().c_str())) {
|
||||
std::uint32_t InstructionNumber;
|
||||
if (pix_dxil::PixDxilInstNum::FromInst(&Inst,
|
||||
&InstructionNumber)) {
|
||||
m_offsets.push_back(InstructionNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,6 +229,8 @@ public:
|
|||
TEST_METHOD(PixTypeManager_SamplersAndResources)
|
||||
TEST_METHOD(PixTypeManager_XBoxDiaAssert)
|
||||
|
||||
TEST_METHOD(DxcPixDxilDebugInfo_InstructionOffsets)
|
||||
|
||||
TEST_METHOD(VirtualRegisters_InstructionCounts)
|
||||
TEST_METHOD(VirtualRegisters_AlignedOffsets)
|
||||
|
||||
|
@ -1803,6 +1805,8 @@ TEST_F(PixTest, PixDebugCompileInfo) {
|
|||
VERIFY_ARE_EQUAL(std::wstring(profile), std::wstring(hlslTarget));
|
||||
}
|
||||
|
||||
static LPCWSTR defaultFilename = L"source.hlsl";
|
||||
|
||||
static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
|
||||
LPWSTR pTargetProfile, std::vector<LPCWSTR> &args,
|
||||
_Outptr_ IDxcBlob **ppResult) {
|
||||
|
@ -1813,7 +1817,7 @@ static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
|
|||
*ppResult = nullptr;
|
||||
VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
|
||||
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(),
|
||||
nullptr, 0, nullptr, &pResult));
|
||||
|
||||
|
@ -2143,6 +2147,178 @@ VSOut main( const uint id : SV_OutputControlPointID,
|
|||
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<IDxcOptimizer> pOptimizer;
|
||||
VERIFY_SUCCEEDED(
|
||||
|
|
Загрузка…
Ссылка в новой задаче