Refactor D3D12 ExecuteIndirect handling to patch arguments on GPU

This commit is contained in:
baldurk
2023-09-18 11:21:50 +01:00
parent cb7048e1a4
commit 55dae7ebc6
23 changed files with 1001 additions and 872 deletions
+110
View File
@@ -133,3 +133,113 @@ uint4 RENDERDOC_DiscardIntPS(float4 pos : SV_Position, out float depth : SV_Dept
return val.xxxx;
}
cbuffer executepatchdata : register(b0)
{
uint argCount;
uint bufCount;
uint argStride;
uint4 argOffsets[32];
};
cbuffer countbuffer : register(b1)
{
uint numExecutes;
};
cbuffer countbuffer : register(b2)
{
uint maxNumExecutes;
};
struct buffermapping
{
// {.x = LSB, .y = MSB} to match uint64 order
uint2 origBase;
uint2 origEnd;
uint2 newBase;
uint2 pad;
};
StructuredBuffer<buffermapping> buffers : register(t0);
RWByteAddressBuffer arguments : register(u0);
bool uint64LessThan(uint2 a, uint2 b)
{
// either MSB is less, or MSB is equal and LSB is less-equal
return a.y < b.y || (a.y == b.y && a.x < b.x);
}
bool uint64LessEqual(uint2 a, uint2 b)
{
return uint64LessThan(a, b) || (a.y == b.y && a.x == b.x);
}
uint2 uint64Add(uint2 a, uint2 b)
{
uint msb = 0, lsb = 0;
if(b.x > 0 && a.x > 0xffffffff - b.x)
{
uint x = max(a.x, b.x) - 0x80000000;
uint y = min(a.x, b.x);
uint sum = x + y;
msb = a.y + b.y + 1;
lsb = sum - 0x80000000;
}
else
{
msb = a.y + b.y;
lsb = a.x + b.x;
}
return uint2(lsb, msb);
}
uint2 uint64Sub(uint2 a, uint2 b)
{
uint msb = 0, lsb = 0;
if(a.x < b.x)
{
uint diff = b.x - a.x;
msb = a.y - b.y - 1;
lsb = 0xffffffff - (diff - 1);
}
else
{
msb = a.y - b.y;
lsb = a.x - b.x;
}
return uint2(lsb, msb);
}
uint2 PatchAddress(uint2 addr)
{
for(uint i = 0; i < bufCount; i++)
{
buffermapping b = buffers[i];
if(uint64LessEqual(b.origBase, addr) && uint64LessThan(addr, b.origEnd))
{
return uint64Add(b.newBase, uint64Sub(addr, b.origBase));
}
}
return addr;
}
[numthreads(128, 1, 1)] void RENDERDOC_ExecuteIndirectPatchCS(uint idx
: SV_GroupIndex) {
if(idx < argCount)
{
for(uint i = 0; i < min(numExecutes, maxNumExecutes); i++)
{
uint offs = argStride * i + argOffsets[idx / 4][idx % 4];
arguments.Store2(offs, PatchAddress(arguments.Load2(offs)));
}
}
}