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);
        }