public static DescriptorHandle operator +(DescriptorHandle handle, int offsetScaledByDescriptorSize) { DescriptorHandle ret = new DescriptorHandle(handle._CPUHandle, handle._GPUHandle); if (handle._CPUHandle.Ptr != -1) { handle._CPUHandle.Ptr += offsetScaledByDescriptorSize; } if (handle._GPUHandle.Ptr != -1) { handle._GPUHandle.Ptr += offsetScaledByDescriptorSize; } return(handle); }
/// <summary> /// The CopyAndBindStaleTables /// </summary> /// <param name="type">The <see cref="DescriptorHeapType"/></param> /// <param name="descriptorSize">The <see cref="uint"/></param> /// <param name="destHandleStart">The <see cref="DescriptorHandle"/></param> /// <param name="setFunction">The <see cref="CommandListSetFunc"/></param> public void CopyAndBindStaleTables(DescriptorHeapType type, uint descriptorSize, DescriptorHandle destHandleStart, CommandListSetFunc setFunction) { uint staleParamCount = 0; var tableSize = new int[MaxNumDescriptorTables]; var rootIndices = new int[MaxNumDescriptorTables]; var needSpace = 0; int rootIndex; var staleParams = StaleRootParamsBitMap; while (BitScanner.BitScanForward(staleParams, out rootIndex)) { rootIndices[staleParamCount] = rootIndex; staleParams ^= (uint)(1 << (int)rootIndex); Debug.Assert(BitScanner.BitScanReverse(RootDescriptorTable[rootIndex].AssignedHandleBitMap, out var maxSetHandle), "Root entry marked as stale but has no stale descriptors"); needSpace += maxSetHandle + 1; tableSize[staleParamCount] = maxSetHandle + 1; staleParamCount++; } Debug.Assert(staleParamCount <= MaxNumDescriptorTables, "We're only equipped to handle so many descriptor tables"); StaleRootParamsBitMap = 0; const uint maxdescriptorPerCopy = 16; var numDestDescriptorRanges = 0; var destDescriptorRangeStarts = new CpuDescriptorHandle[maxdescriptorPerCopy]; var destDescriptorRangeSizes = new int[maxdescriptorPerCopy]; var numSrcDescriptorRanges = 0; var srcDescriptorRangeStarts = new CpuDescriptorHandle[maxdescriptorPerCopy]; var srcDescriptorRangeSizes = new int[maxdescriptorPerCopy]; for (uint idx = 0; idx < staleParamCount; idx++) { rootIndex = rootIndices[idx]; setFunction?.Invoke((int)rootIndex, destHandleStart.GPUHandle); var rootDescTable = RootDescriptorTable[rootIndex]; var srcHandles = rootDescTable.TableStart; UInt64 setHandles = rootDescTable.AssignedHandleBitMap; var curDest = destHandleStart.CPUHandle; destHandleStart += (int)(tableSize[idx] * descriptorSize); while (BitScanner.BitScanForward64(setHandles, out var skipCount)) { setHandles >>= skipCount; srcHandles += skipCount; curDest.Ptr += skipCount * descriptorSize; BitScanner.BitScanForward64(~setHandles, out var descriptorCount); setHandles >>= descriptorCount; if (numSrcDescriptorRanges + descriptorCount > maxdescriptorPerCopy) { Globals.Device.CopyDescriptors(numDestDescriptorRanges, destDescriptorRangeStarts, destDescriptorRangeSizes, numSrcDescriptorRanges, srcDescriptorRangeStarts, srcDescriptorRangeSizes, type); numSrcDescriptorRanges = 0; numDestDescriptorRanges = 0; } destDescriptorRangeStarts[numDestDescriptorRanges] = curDest; destDescriptorRangeSizes[numDestDescriptorRanges] = descriptorCount; numDestDescriptorRanges++; for (int jdx = 0; jdx < descriptorCount; jdx++) { srcDescriptorRangeStarts[numSrcDescriptorRanges] = Marshal.PtrToStructure <CpuDescriptorHandle>(rootDescTable.TableStart + jdx * Marshal.SizeOf <CpuDescriptorHandle>()); srcDescriptorRangeSizes[numSrcDescriptorRanges] = 1; numSrcDescriptorRanges++; } srcHandles += descriptorCount; curDest.Ptr += descriptorCount; } } Globals.Device.CopyDescriptors(numDestDescriptorRanges, destDescriptorRangeStarts, destDescriptorRangeSizes, numSrcDescriptorRanges, srcDescriptorRangeStarts, srcDescriptorRangeSizes, type); }