@@ -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+
65746606bool 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
73987434void 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
0 commit comments