public Boolean StageDescriptorHandles(Int32 rootIndex, Int32 offset, Int32 numHandles, CpuDescriptorHandle[] handles) { if (m_RootDescriptorTableBitMap[rootIndex] == false) { // root parameter is not a CBV_SRV_UAV descriptor table return(false); } // descriptor table is out of boundary by handles(descriptor handles) if (offset + numHandles > m_RootDescriptorTable[rootIndex].TableSize) { return(false); } H1DescriptorTableCache tableCache = m_RootDescriptorTable[rootIndex]; // set handles to handle caches for descriptor table cache Int32 copyDestIndex = tableCache.TableStart + offset; for (Int32 i = 0; i < numHandles; ++i) { m_HandleCaches[copyDestIndex + i] = handles[i]; tableCache.AssignedHandlesBitMap[offset + i] = true; } // set root param bit map as true m_StaleRootParamsBitMap[rootIndex] = true; return(true); }
public Boolean ParseRootSignature(H1RootSignature rootSignature) { Int32 currentOffset = 0; // maybe we need to support something greater if (rootSignature.NumParameters > 16) { return(false); } for (Int32 i = 0; i < m_StaleRootParamsBitMap.Count; ++i) { m_StaleRootParamsBitMap[i] = false; } for (Int32 i = 0; i < rootSignature.DescriptorTableBitArray.Count; ++i) { m_RootDescriptorTableBitMap[i] = rootSignature.DescriptorTableBitArray[i]; } BitArray tableParams = m_RootDescriptorTableBitMap; for (Int32 rootIndex = 0; rootIndex < tableParams.Count; ++rootIndex) { // bit scanning forward if (tableParams[rootIndex] == true) { Int32 tableSize = rootSignature.DescriptorTableSize[rootIndex]; // the invalid table size is smaller and equal than zero if (tableSize <= 0) { return(false); } H1DescriptorTableCache rootDescriptorTable = m_RootDescriptorTable[rootIndex]; rootDescriptorTable.TableSize = tableSize; rootDescriptorTable.TableStart = currentOffset; for (Int32 i = 0; i < rootDescriptorTable.AssignedHandlesBitMap.Count; ++i) { rootDescriptorTable.AssignedHandlesBitMap[i] = false; } currentOffset++; } } m_MaxCachedDescriptors = currentOffset; return(true); }
public Boolean CopyAndBindStaleTables(H1DescriptorHandle destHandleStart, GraphicsCommandList cmdList, Boolean bGraphicsRootDescriptorTable = true) { Int64 staleParamCount = 0; Int64[] tableSize = new Int64[MaxNumDescriptorsTables]; Int64[] rootIndices = new Int64[MaxNumDescriptorsTables]; Int64 neededSpace = 0; Int32 rootIndex; // sum the maximum assigned offsets of stale descriptor tables to determine total needed space BitArray staleParams = m_StaleRootParamsBitMap; for (rootIndex = 0; rootIndex < staleParams.Count; ++rootIndex) { // forward bit scanning if (staleParams[rootIndex] == true) { // cache stale parameter index to the root indices rootIndices[staleParamCount] = rootIndex; // XOR to staleParams staleParams[rootIndex] = false; BitArray AssignedHandlesForRootDescriptorTable = m_RootDescriptorTable[rootIndex].AssignedHandlesBitMap; for (Int32 maxSetHandle = AssignedHandlesForRootDescriptorTable.Count - 1; maxSetHandle >= 0; --maxSetHandle) { // bit reverse traversing if (AssignedHandlesForRootDescriptorTable[maxSetHandle] == true) { neededSpace += maxSetHandle + 1; tableSize[staleParamCount] = maxSetHandle + 1; break; // only take an account of maximum handle index } } // increase stale param count staleParamCount++; } } if (staleParamCount > MaxNumDescriptorsTables) { return(false); // only equipped to handle so many descriptor tables } // clear stale root param bit map for (int i = 0; i < m_StaleRootParamsBitMap.Count; ++i) { m_StaleRootParamsBitMap[i] = false; } const Int32 MaxDescriptorPerCopy = 16; Int32 numDestDescriptorRanges = 0; CpuDescriptorHandle[] destDescriptorRangeStart = new CpuDescriptorHandle[MaxDescriptorPerCopy]; Int32[] destDescriptorRangeSizes = new Int32[MaxDescriptorPerCopy]; Int32 numSrcDescriptorRanges = 0; CpuDescriptorHandle[] srcDescriptorRangeStart = new CpuDescriptorHandle[MaxDescriptorPerCopy]; Int32[] srcDescriptorRangeSizes = new Int32[MaxDescriptorPerCopy]; Int32 descriptorSize = H1DynamicDescriptorHeap.GetDescriptorSize(); for (Int32 i = 0; i < staleParamCount; ++i) { // get the root index and set root descriptor table rootIndex = Convert.ToInt32(rootIndices[i]); if (bGraphicsRootDescriptorTable) { cmdList.SetGraphicsRootDescriptorTable(rootIndex, destHandleStart.GpuHandle); } else { cmdList.SetComputeRootDescriptorTable(rootIndex, destHandleStart.GpuHandle); } H1DescriptorTableCache rootDescriptorTable = m_RootDescriptorTable[rootIndex]; // cached local variables Int32 srcHandles = rootDescriptorTable.TableStart; BitArray setHandles = rootDescriptorTable.AssignedHandlesBitMap; CpuDescriptorHandle currDest = destHandleStart.CpuHandle; // move dest handle start ptr by table size scaled by descriptor size destHandleStart = destHandleStart + (tableSize[i] * descriptorSize); for (Int32 skipCount = 0; skipCount < setHandles.Count; ++skipCount) { // forward bit scanning if (setHandles[skipCount] == true) { // skip over unset descriptor handles srcHandles += skipCount; currDest.Ptr += skipCount * descriptorSize; Int32 descriptorCount; for (descriptorCount = skipCount; descriptorCount < setHandles.Count; ++descriptorCount) { // find unset descriptor handles (skipping consecutive set descriptor handles) if (setHandles[descriptorCount] == false) { // update descriptorCount as consecutive set descriptor handles descriptorCount -= skipCount; // update skipCount skipCount += descriptorCount; break; } } // if we run out of temp room, copy that we've got so far if (numDestDescriptorRanges + descriptorCount > MaxDescriptorPerCopy) { H1Global <H1ManagedRenderer> .Instance.Device.CopyDescriptors( numDestDescriptorRanges, destDescriptorRangeStart, destDescriptorRangeSizes, numSrcDescriptorRanges, srcDescriptorRangeStart, srcDescriptorRangeSizes, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); // reset the number of [src|dest] descriptor range numbers numSrcDescriptorRanges = 0; numDestDescriptorRanges = 0; } // set up destination range destDescriptorRangeStart[numDestDescriptorRanges] = currDest; destDescriptorRangeSizes[numDestDescriptorRanges] = descriptorCount; ++numDestDescriptorRanges; // set up source ranges (one descriptor each because we don't assume they are contiguous) for (Int32 j = 0; j < descriptorCount; ++j) { srcDescriptorRangeStart[numSrcDescriptorRanges] = m_HandleCaches[srcHandles + j]; srcDescriptorRangeSizes[numSrcDescriptorRanges] = 1; ++numSrcDescriptorRanges; } // move the destination pointer forward by the number of descriptors we will copy srcHandles += descriptorCount; currDest.Ptr += descriptorCount * descriptorCount; } } } H1Global <H1ManagedRenderer> .Instance.Device.CopyDescriptors( numDestDescriptorRanges, destDescriptorRangeStart, destDescriptorRangeSizes, numSrcDescriptorRanges, srcDescriptorRangeStart, srcDescriptorRangeSizes, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); return(true); }