Skip to content

Commit a704828

Browse files
committed
DXIL Debugger Load operations copy from backing memory
Don't use the cached value, fixes problems with GSM on a POD type (not array) Atomic operations always load GSM from global backing memory
1 parent f9788d1 commit a704828

File tree

2 files changed

+64
-15
lines changed

2 files changed

+64
-15
lines changed

renderdoc/driver/shaders/dxil/dxil_debug.cpp

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5201,11 +5201,11 @@ bool ThreadState::ExecuteInstruction(const rdcarray<ThreadState> &workgroup)
52015201
result.value = arg.value;
52025202
break;
52035203
}
5204-
case Operation::Load: OperationLoad(inst, opCode, dxOpCode, resultId, result); break;
5204+
case Operation::Load: OperationLoad(false, inst, opCode, dxOpCode, resultId, result); break;
52055205
case Operation::LoadAtomic:
52065206
{
52075207
SCOPED_LOCK(m_Debugger.GetAtomicMemoryLock());
5208-
OperationLoad(inst, opCode, dxOpCode, resultId, result);
5208+
OperationLoad(true, inst, opCode, dxOpCode, resultId, result);
52095209
break;
52105210
}
52115211
case Operation::Store:
@@ -6571,6 +6571,38 @@ void ThreadState::UpdateGlobalBackingMemory(Id ptrId, const MemoryTracking::Poin
65716571
}
65726572
}
65736573

6574+
bool ThreadState::LoadGSMFromGlobalBackingMemory(const MemoryTracking::Pointer &ptr,
6575+
const MemoryTracking::Allocation &allocation,
6576+
ShaderVariable &var)
6577+
{
6578+
const Id baseMemoryId = ptr.baseMemoryId;
6579+
auto globalMem = m_GlobalState.memory.m_Allocations.find(baseMemoryId);
6580+
if(globalMem != m_GlobalState.memory.m_Allocations.end())
6581+
{
6582+
// Compute the local pointer offset and apply it to the global base memory
6583+
ptrdiff_t offset = (uintptr_t)ptr.memory - (uintptr_t)allocation.backingMemory;
6584+
if(offset >= 0)
6585+
{
6586+
const void *globalBackingMemory = globalMem->second.backingMemory;
6587+
void *globalMemory = (void *)((uintptr_t)globalBackingMemory + offset);
6588+
RDCASSERT(ptr.size <= sizeof(ShaderValue));
6589+
if(ptr.size <= sizeof(ShaderValue))
6590+
memcpy(&var.value, globalMemory, (size_t)ptr.size);
6591+
}
6592+
else
6593+
{
6594+
RDCERR("Invalid memory allocation offset baseMemoryId %u", baseMemoryId);
6595+
return false;
6596+
}
6597+
}
6598+
else
6599+
{
6600+
RDCERR("Invalid GSM baseMemoryId %u", baseMemoryId);
6601+
return false;
6602+
}
6603+
return true;
6604+
}
6605+
65746606
bool ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroup, Operation opCode,
65756607
DXOp dxOpCode, const ResourceReferenceInfo &resRefInfo,
65766608
const DXIL::Instruction &inst, ShaderVariable &result)
@@ -7350,7 +7382,7 @@ void ThreadState::QueueSampleGather(DXIL::DXOp dxOp, const SampleGatherResourceD
73507382
SetStepNeedsGpuSampleGatherOp();
73517383
}
73527384

7353-
void ThreadState::OperationLoad(const DXIL::Instruction &inst, DXIL::Operation opCode,
7385+
void ThreadState::OperationLoad(bool isAtomic, const DXIL::Instruction &inst, DXIL::Operation opCode,
73547386
DXIL::DXOp dxOpCode, Id &resultId, ShaderVariable &result)
73557387
{
73567388
if(DXIL::IsDXCNop(inst))
@@ -7381,18 +7413,22 @@ void ThreadState::OperationLoad(const DXIL::Instruction &inst, DXIL::Operation o
73817413
RDCERR("Unknown memory allocation Id %u", baseMemoryId);
73827414
return;
73837415
}
7416+
73847417
const MemoryTracking::Allocation &allocation = itAlloc->second;
7385-
ShaderVariable arg;
7386-
if(allocation.globalVarAlloc && !IsVariableAssigned(ptrId))
7418+
// active lane: Atomic Load for GSM then read from the global backing memory
7419+
if(m_HasDebugState && isAtomic && allocation.gsm)
73877420
{
7388-
RDCASSERT(IsVariableAssigned(baseMemoryId));
7389-
arg = m_Variables[baseMemoryId];
7421+
if(!LoadGSMFromGlobalBackingMemory(ptr, allocation, result))
7422+
RDCERR("OperationLoad: LoadGSMFromGlobalBackingMemory failed ptrId %u", ptrId);
7423+
return;
73907424
}
7425+
7426+
// Load from local backing memory
7427+
RDCASSERT(ptr.size <= sizeof(ShaderValue));
7428+
if(ptr.size <= sizeof(ShaderValue))
7429+
memcpy(&result.value, ptr.memory, (size_t)ptr.size);
73917430
else
7392-
{
7393-
RDCASSERT(GetShaderVariable(inst.args[0], opCode, dxOpCode, arg));
7394-
}
7395-
result.value = arg.value;
7431+
RDCERR("Size %u too large MAX %u for OperationLoad", ptr.size, sizeof(ShaderValue));
73967432
}
73977433

73987434
void ThreadState::OperationStore(const DXIL::Instruction &inst, DXIL::Operation opCode,
@@ -7440,7 +7476,7 @@ void ThreadState::OperationStore(const DXIL::Instruction &inst, DXIL::Operation
74407476
UpdateMemoryVariableFromBackingMemory(baseMemoryId, allocation.backingMemory);
74417477

74427478
// active lane : writes to a GSM variable, write to local and global backing memory
7443-
if(m_HasDebugState)
7479+
if(m_HasDebugState && allocation.gsm)
74447480
UpdateGlobalBackingMemory(ptrId, ptr, allocation, val);
74457481

74467482
// record the change to the base memory variable if it is not the ptrId variable
@@ -7517,6 +7553,16 @@ void ThreadState::OperationAtomic(const DXIL::Instruction &inst, DXIL::Operation
75177553
a = m_Variables[ptrId];
75187554
}
75197555

7556+
// GSM variable, read from the global backing memory
7557+
if(allocation.gsm)
7558+
{
7559+
if(!LoadGSMFromGlobalBackingMemory(ptr, allocation, a))
7560+
{
7561+
RDCERR("OperationAtomic: LoadGSMFromGlobalBackingMemory failed ptrId %u", ptrId);
7562+
return;
7563+
}
7564+
}
7565+
75207566
size_t newValueArgIdx = (opCode == Operation::CompareExchange) ? 2 : 1;
75217567
ShaderVariable b;
75227568
RDCASSERT(GetShaderVariable(inst.args[newValueArgIdx], opCode, dxOpCode, b));
@@ -7639,7 +7685,7 @@ void ThreadState::OperationAtomic(const DXIL::Instruction &inst, DXIL::Operation
76397685
UpdateMemoryVariableFromBackingMemory(baseMemoryId, allocMemoryBackingPtr);
76407686

76417687
// active lane : writes to a GSM variable, write to local and global backing memory
7642-
if(m_HasDebugState)
7688+
if(m_HasDebugState && allocation.gsm)
76437689
UpdateGlobalBackingMemory(ptrId, ptr, allocation, res);
76447690

76457691
// record the change to the base memory variable

renderdoc/driver/shaders/dxil/dxil_debug.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,9 @@ struct ThreadState
624624
void UpdateGlobalBackingMemory(Id ptrId, const MemoryTracking::Pointer &ptr,
625625
const MemoryTracking::Allocation &allocation,
626626
const ShaderVariable &val);
627+
bool LoadGSMFromGlobalBackingMemory(const MemoryTracking::Pointer &ptr,
628+
const MemoryTracking::Allocation &allocation,
629+
ShaderVariable &var);
627630

628631
bool PerformGPUResourceOp(const rdcarray<ThreadState> &workgroup, DXIL::Operation opCode,
629632
DXIL::DXOp dxOpCode, const ResourceReferenceInfo &resRef,
@@ -663,8 +666,8 @@ struct ThreadState
663666
const int8_t texelOffsets[3], int multisampleIndex, float lodValue,
664667
float compareValue, GatherChannel gatherChannel, uint32_t instructionIdx,
665668
ShaderVariable &result);
666-
void OperationLoad(const DXIL::Instruction &inst, DXIL::Operation opCode, DXIL::DXOp dxOpCode,
667-
Id &resultId, ShaderVariable &result);
669+
void OperationLoad(bool isAtomic, const DXIL::Instruction &inst, DXIL::Operation opCode,
670+
DXIL::DXOp dxOpCode, Id &resultId, ShaderVariable &result);
668671
void OperationStore(const DXIL::Instruction &inst, DXIL::Operation opCode, DXIL::DXOp dxOpCode);
669672
void OperationAtomic(const DXIL::Instruction &inst, DXIL::Operation opCode, DXIL::DXOp dxOpCode,
670673
Id &resultId, ShaderVariable &result);

0 commit comments

Comments
 (0)