//! Some members are computed based on the value of other members. If the latter //! are changed after construction, the former must be re-computed. void Dsettings :: update() { assert(is_powerOf2(numChannels)); assert(is_powerOf2(numRanks)); assert(is_powerOf2(numBanks)); assert(is_powerOf2(numRows)); assert(is_powerOf2(numColumns)); this->numDatabusPackets = (int) ((this->llcacheLineSizeBytes*8)/this->channelBitWidth); this->t_RC = this->t_RAS + this->t_RP; this->t_RTP = this->t_RAS - this->t_RCD; this->t_CWD = (this->t_CAS - 1); this->t_RFC = this->numRows*(this->t_RC); this->rowShiftBits = (int) (myLog2(this->numColumns)); this->bankShiftBits = ((int) (myLog2(this->numRows))) + this->rowShiftBits; this->rankShiftBits = ((int) (myLog2(this->numBanks))) + this->bankShiftBits; this->channelShiftBits = ((int) (myLog2(this->numRanks))) + this->rankShiftBits; //this->rowMask = this->getMask(this->numRows); //this->bankMask = this->getMask(this->numBanks); //this->rankMask = this->getMask(this->numRanks); this->rowMask = this->getMask(myLog2(this->numRows)); this->bankMask = this->getMask(myLog2(this->numBanks)); this->rankMask = this->getMask(myLog2(this->numRanks)); }
Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); unsigned long size, alloced, align = 0; int i; Bool tileable; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); int verbosity = dryrun ? 4 : 1; const char *s = dryrun ? "[dryrun] " : ""; int lines; DPRINTF(PFX, "I830Allocate3DMemory\n"); /* Back Buffer */ memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); pI830->BackBuffer.Key = -1; tileable = !(flags & ALLOC_NO_TILING) && IsTileable(pScrn->displayWidth * pI830->cpp); if (tileable) { /* Make the height a multiple of the tile height (16) */ lines = (pScrn->virtualY + 15) / 16 * 16; } else { lines = pScrn->virtualY; } size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); /* * Try to allocate on the best tile-friendly boundaries. */ alloced = 0; if (tileable) { align = GetBestTileAlignment(size); for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) { alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), &(pI830->StolenPool), size, align, flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | ALIGN_BOTH_ENDS); if (alloced >= size) break; } } if (alloced < size) { /* Give up on trying to tile */ tileable = FALSE; size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); align = GTT_PAGE_SIZE; alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), &(pI830->StolenPool), size, align, flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); } if (alloced < size) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate back buffer space.\n"); } return FALSE; } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sAllocated %d kB for the back buffer at 0x%x.\n", s, alloced / 1024, pI830->BackBuffer.Start); /* Depth Buffer -- same size as the back buffer */ memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); pI830->DepthBuffer.Key = -1; /* * Try to allocate on the best tile-friendly boundaries. */ alloced = 0; if (tileable) { /* Start with the previous align value. */ for (; align >= KB(512); align >>= 1) { alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), &(pI830->StolenPool), size, align, flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | ALIGN_BOTH_ENDS); if (alloced >= size) break; } } if (alloced < size) { /* Give up on trying to tile */ tileable = FALSE; size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); align = GTT_PAGE_SIZE; alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), &(pI830->StolenPool), size, align, flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); } if (alloced < size) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate depth buffer space.\n"); } return FALSE; } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sAllocated %d kB for the depth buffer at 0x%x.\n", s, alloced / 1024, pI830->DepthBuffer.Start); /* Space for logical context. 32k is fine for right now. */ memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); pI830->ContextMem.Key = -1; size = KB(32); alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem), &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); if (alloced < size) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate logical context space.\n"); } return FALSE; } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sAllocated %d kB for the logical context at 0x%x.\n", s, alloced / 1024, pI830->ContextMem.Start); /* * Space for DMA buffers, only if there's enough free for at least 1MB * of texture space. */ memset(&(pI830->BufferMem), 0, sizeof(pI830->BufferMem)); pI830->BufferMem.Key = -1; /* This should already be a page multiple */ size = I830_DMA_BUF_NR * I830_DMA_BUF_SZ; if (dryrun || (GetFreeSpace(pScrn) >= size + MB(1))) { alloced = I830AllocVidMem(pScrn, &(pI830->BufferMem), &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); if (alloced < size) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate DMA buffer space.\n"); } return FALSE; } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sAllocated %d kB for the DMA buffers at 0x%x.\n", s, alloced / 1024, pI830->BufferMem.Start); } else { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough free space for DMA buffers.\n"); } return FALSE; } /* Allocate the remaining space for textures. */ memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); pI830->TexMem.Key = -1; size = GetFreeSpace(pScrn); if (dryrun && (size < MB(1))) size = MB(1); i = myLog2(size / I830_NR_TEX_REGIONS); if (i < I830_LOG_MIN_TEX_REGION_SIZE) i = I830_LOG_MIN_TEX_REGION_SIZE; pI830->TexGranularity = i; /* Truncate size */ size >>= i; size <<= i; if (size < KB(512)) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Less than %d kBytes for texture space.\n", size / 1024); } return FALSE; } alloced = I830AllocVidMem(pScrn, &(pI830->TexMem), &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); if (alloced < size) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate texture space.\n"); } return FALSE; } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sAllocated %d kB for textures at 0x%x\n", s, alloced / 1024, pI830->TexMem.Start); return TRUE; }
Dsettings::Dsettings( int numChannels, int numRanks, int numBanks, int numRows, int numColumns, int channelBitWidth, int llcacheLineSizeBytes, int memPagePolicy, /********************** Timing Parameters ***************/ unsigned long t_RTRS, unsigned long t_OST, unsigned long t_BURST, unsigned long t_RAS, unsigned long t_RP, unsigned long t_RCD, unsigned long t_CCD, unsigned long t_CAS, unsigned long t_CMD, unsigned long t_WR, unsigned long t_WTR, unsigned long t_FAW, unsigned long t_RRD ) { assert(is_powerOf2(numChannels)); assert(is_powerOf2(numRanks)); assert(is_powerOf2(numBanks)); assert(is_powerOf2(numRows)); assert(is_powerOf2(numColumns)); /********************** Memory Config *******************/ this->numChannels = numChannels; this->numRanks = numRanks; this->numBanks = numBanks; this->numRows = numRows; this->numColumns = numColumns; this->channelBitWidth = channelBitWidth; this->llcacheLineSizeBytes = llcacheLineSizeBytes; this->memPagePolicy = OPEN_PAGE; this->numDatabusPackets = (int) ((this->llcacheLineSizeBytes*8)/this->channelBitWidth); /********************** Timing Parameters ***************/ this->t_RTRS = t_RTRS; this->t_OST = t_OST; this->t_BURST = t_BURST; this->t_RAS = t_RAS; this->t_RP = t_RP; this->t_RCD = t_RCD; this->t_CCD = t_CCD; this->t_CAS = t_CAS; this->t_CMD = t_CMD; this->t_WR = t_WR; this->t_WTR = t_WTR; this->t_FAW = t_FAW; this->t_RRD = t_RRD; this->t_RC = this->t_RAS + this->t_RP; this->t_RTP = this->t_RAS - this->t_RCD; this->t_CWD = (this->t_CAS - 1); this->t_RFC = this->numRows*(this->t_RC); /************** Dreq Helper Variables ********************/ this->rowShiftBits = (int) (myLog2(this->numColumns)); this->bankShiftBits = ((int) (myLog2(this->numRows))) + this->rowShiftBits; this->rankShiftBits = ((int) (myLog2(this->numBanks))) + this->bankShiftBits; this->channelShiftBits = ((int) (myLog2(this->numRanks))) + this->rankShiftBits; //this->rowMask = this->getMask(this->numRows); //this->bankMask = this->getMask(this->numBanks); //this->rankMask = this->getMask(this->numRanks); this->rowMask = this->getMask(myLog2(this->numRows)); this->bankMask = this->getMask(myLog2(this->numBanks)); this->rankMask = this->getMask(myLog2(this->numRanks)); }
//! Test if a number is a power of 2. bool Dsettings :: is_powerOf2(unsigned num) { int bits = myLog2(num); return ((unsigned)(0x1 << bits) == num); }
float myPow(float a, float b) { return myPow2(b * myLog2(a)); }