// 'end' as parameter is assigned value
 public H1GpuMemoryBlock(H1GpuMemoryPageSegmented pageRef, Int32 start, Int32 counts)
 {
     m_PageRef           = pageRef;
     m_PageSegmentStart  = start;
     m_PageSegmentEnd    = m_PageSegmentStart + counts - 1;
     m_PageSegmentCounts = counts;
 }
        protected Boolean UpdateAvailableMemoryPageSegmented()
        {
            Int32 maxEvaluatedValue = Int32.MinValue;
            Int32 maxPageIndex      = -1;

            for (Int32 pageIndex = 0; pageIndex < m_Pages.Count; ++pageIndex)
            {
                H1GpuMemoryPageSegmented page = m_Pages[pageIndex] as H1GpuMemoryPageSegmented;
                if (page == null) // invalid memory page type (should be segmented type)
                {
                    return(false);
                }

                Int32 evaluatedValue = page.LargestAvailableSegmentCounts;
                if (maxEvaluatedValue < evaluatedValue)
                {
                    maxPageIndex      = pageIndex;
                    maxEvaluatedValue = evaluatedValue;
                }
            }

            // set available memory page which has largest available memory
            m_AvailablePage = m_Pages[maxPageIndex] as H1GpuMemoryPageSegmented;
            return(true);
        }
        protected static Boolean SetupPageSegments(H1GpuMemoryPageSegmented memoryPageRef, Int32 segmentCounts)
        {
            if (memoryPageRef == null)
            {
                return(false);
            }

            if (segmentCounts <= 0)
            {
                return(false);
            }

            // initialize all related page segments properties
            memoryPageRef.m_AllocBits    = new BitArray(segmentCounts, false);
            memoryPageRef.m_PageSegments = new PageSegment[segmentCounts];

            // initialize page segments
            Int32 currOffset = 0;

            foreach (PageSegment pageSegment in memoryPageRef.m_PageSegments)
            {
                pageSegment.Offset = currOffset++;
            }

            return(true);
        }
        protected void CreateNewPageSegmented()
        {
            H1GpuMemoryPageSegmented newPage = H1GpuMemoryPageSegmented.CreatePage(this);

            m_Pages.Add(newPage);

            // update available page as newly created page
            m_AvailablePage = newPage;
        }
        // newly override method called 'CreatePage(...)'
        public new static H1GpuMemoryPageSegmented CreatePage(H1GpuMemoryChunk memoryChunk)
        {
            H1GpuMemoryPageSegmented newPage = new H1GpuMemoryPageSegmented(memoryChunk);

            // create resource encapsulated GPU API layer
            H1HeapType       heapType = H1HeapType.Unknown;
            H1ResourceStates usage    = H1ResourceStates.Invalid;

            H1GpuResourceDesc resourceDesc = new H1GpuResourceDesc();

            resourceDesc.Alignment          = 0;
            resourceDesc.Height             = 1;
            resourceDesc.DepthOrArraySize   = 1;
            resourceDesc.MipLevels          = 1;
            resourceDesc.Format             = H1PixelFormat.Unknown;
            resourceDesc.SampleDesc.Count   = 1;
            resourceDesc.SampleDesc.Quality = 0;
            resourceDesc.Layout             = H1TextureLayout.RowMajor;

            // CPU-writable
            if (newPage.Owner.Type == H1GpuMemoryType.GpuWritable)
            {
                heapType = H1HeapType.Default;

                resourceDesc.Width = Convert.ToUInt32(H1GpuMemoryPageSize.GpuWritablePageSize);
                resourceDesc.Flags = H1ResourceFlags.AllowUnorderedAccess;
                resourceDesc.Flags = H1ResourceFlags.Unknown;

                usage = H1ResourceStates.UnorderedAccess;
            }

            // GPU-writable
            else if (newPage.Owner.Type == H1GpuMemoryType.CpuWritable)
            {
                // cpu writable is mainly for upload page (it could be 'readback' property)
                heapType = H1HeapType.Upload;

                resourceDesc.Width = Convert.ToUInt32(H1GpuMemoryPageSize.CpuWritablePageSize);
                resourceDesc.Flags = H1ResourceFlags.Unknown;

                usage = H1ResourceStates.GenericRead;
            }

            // @TODO - handle 'Readback' heap type
            else
            {
                // invalid type is assigned!
                return(null);
            }

            // create new page resource
            //if (!newPage.Resource.CreateResource(heapType, resourceDesc, usage))
            {
                return(null);
            }

            // initialize the properties of the gpu memory page
            Int32 segmentCounts = -1;

            // calculate segment counts
            // @TODO - need to consider further for choosing segment counts (kinda magic number)
            if (newPage.Owner.Type == H1GpuMemoryType.GpuWritable)
            {
                segmentCounts = 1 << 8; // 256 segments
                newPage.m_PageSegmentCounts = segmentCounts;
                newPage.m_PageSegmentSize   = Convert.ToInt32(H1GpuMemoryPageSize.GpuWritablePageSize) / newPage.m_PageSegmentCounts;
            }

            else if (newPage.Owner.Type == H1GpuMemoryType.CpuWritable)
            {
                segmentCounts = 1 << 10; // 1024 segments
                newPage.m_PageSegmentCounts = segmentCounts;
                newPage.m_PageSegmentSize   = Convert.ToInt32(H1GpuMemoryPageSize.CpuWritablePageSize) / newPage.m_PageSegmentCounts;
            }

            if (!SetupPageSegments(newPage, segmentCounts))
            {
                return(null);
            }

            return(newPage);
        }