rem: * because on lower acc_masks bandwidth trouble arises (pixel noise). */
add: * because on lower acc_masks more bandwidth trouble arises. * (pixel noise) */
context: status_t nm_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode){	/* Note:	 * This routine assumes that the CRTC memory pitch granularity is 'smaller than',	 * or 'equals' the acceleration engine memory pitch granularity! */	uint32 video_pitch = 0;	uint32 crtc_mask;	uint8 depth = 8;	/* determine pixel multiple based on CRTC memory pitch constraints.	 * (Note: Don't mix this up with CRTC timing contraints! Those are	 *        multiples of 8 for horizontal, 1 for vertical timing.)	 *	 * CRTC pitch constraints are 'officially' the same for all Neomagic cards */	switch (si->ps.card_type)	{	case NM2070:		switch (target->space)		{			case B_CMAP8: crtc_mask = 0x07; depth =  8; break;			/* Note for NM2070 only:			 * The following depths have bandwidth trouble (pixel noise) with the			 * 'official' crtc_masks (used as defaults below). Masks of 0x1f are			 * needed (confirmed 15 and 16 bit spaces) to prevent this from occuring. */			//fixme: doublecheck for NM2090 and NM2093: correct code if needed!			case B_RGB15: crtc_mask = 0x1f; depth = 16; break;			case B_RGB16: crtc_mask = 0x1f; depth = 16; break;			case B_RGB24: crtc_mask = 0x1f; depth = 24; break; 			default:				LOG(8,("INIT: unsupported colorspace: 0x%08x\n", target->space));				return B_ERROR;		}		break;	default:		switch (target->space)		{			case B_CMAP8: crtc_mask = 0x07; depth =  8; break;			case B_RGB15: crtc_mask = 0x03; depth = 16; break;			case B_RGB16: crtc_mask = 0x03; depth = 16; break;			case B_RGB24: crtc_mask = 0x07; depth = 24; break; 			default:				LOG(8,("INIT: unsupported colorspace: 0x%08x\n", target->space));				return B_ERROR;		}		break;	}	/* check if we can setup this mode with acceleration: */	*acc_mode = true;	switch (si->ps.card_type)	{	case NM2070:	case NM2097:	case NM2160:		if (target->space != B_RGB24) *acc_mode = true;		else *acc_mode = false;		break;	default:		*acc_mode = false;		break;	}	/* virtual_width */	if (si->ps.card_type == NM2070)	{		/* confirmed NM2070 */		if (target->virtual_width > 1024) *acc_mode = false;	}	else	{		/* confirmed for all cards */		if (target->virtual_width > 1600) *acc_mode = false;	}	/* virtual_height */	if (si->ps.card_type < NM2200)	{		/* confirmed NM2070, NM2097 and NM2160 */		if (target->virtual_height > 1024) *acc_mode = false;	}	else	{		/* fixme: needs confirmation, assuming this height will still work.. */		if (target->virtual_height > 2048) *acc_mode = false;	}	/* now check virtual_size based on CRTC constraints and modify if needed *///fixme: checkout cardspecs here!! (NM2160 can do 8192 _bytes_ at least (in theory))	{		/* virtual_width */		switch(target->space)		{		case B_CMAP8:			if (target->virtual_width > 16368)				target->virtual_width = 16368;			break;		case B_RGB15_LITTLE:		case B_RGB16_LITTLE:			if (target->virtual_width > 8184)				target->virtual_width = 8184;			break;		case B_RGB24_LITTLE:			if (target->virtual_width > 5456)				target->virtual_width = 5456;			break;		}		/* virtual_height: The only constraint here is the cards memory size which is		 * checked later on in ProposeMode: virtual_height is adjusted then if needed.		 * 'Limiting here' to the variable size that's at least available (uint16). */		if (target->virtual_height > 65535) target->virtual_height = 65535;	}	/* OK, now we know that virtual_width is valid, and it's needing no slopspace if	 * it was confined above, so we can finally calculate safely if we need slopspace	 * for this mode... */	if (*acc_mode)	{		if (si->ps.card_type == NM2070)		{			uint32 acc_mask = 0;			/* determine pixel multiple based on 2D engine constraints */			switch (target->space)			{				case B_CMAP8: acc_mask = 0x07; break;				/* Note:				 * The following depths have actual acc_masks of 0x03. 0x1f is used				 * because on lower acc_masks bandwidth trouble arises (pixel noise). */				//fixme: doublecheck for NM2090 and NM2093: correct code if needed!				case B_RGB15: acc_mask = 0x1f; break;				case B_RGB16: acc_mask = 0x1f; break;			}			video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask);		}		else		{			/* Note:			 * We prefer unaccelerated modes above accelerated ones here if not enough			 * RAM exists and the mode can be closer matched to the requested one if			 * unaccelerated. We do this because of the large amount of slopspace			 * sometimes needed here to keep a mode accelerated. */			uint32 mem_avail, bytes_X_height;			/* calculate amount of available memory */			mem_avail = (si->ps.memory_size * 1024);			if (si->settings.hardcursor) mem_avail -= si->ps.curmem_size;			/* helper */			bytes_X_height = (depth >> 3) * target->virtual_height;			/* Accelerated modes work with a table, there are very few fixed settings.. */			if (target->virtual_width == 640) video_pitch = 640;			else				if (target->virtual_width <= 800)				{					if (((800 * bytes_X_height) > mem_avail) &&						(target->virtual_width < (800 - crtc_mask)))						*acc_mode = false;					else						video_pitch = 800;				}				else					if (target->virtual_width <= 1024)					{						if (((1024 * bytes_X_height) > mem_avail) &&							(target->virtual_width < (1024 - crtc_mask)))							*acc_mode = false;						else							video_pitch = 1024;					}					else						if (target->virtual_width <= 1152)						{							if (((1152 * bytes_X_height) > mem_avail) &&								(target->virtual_width < (1152 - crtc_mask)))								*acc_mode = false;							else								video_pitch = 1152;						}						else							if (target->virtual_width <= 1280)							{								if (((1280 * bytes_X_height) > mem_avail) &&									(target->virtual_width < (1280 - crtc_mask)))									*acc_mode = false;								else									video_pitch = 1280;							}							else								if (target->virtual_width <= 1600)								{									if (((1600 * bytes_X_height) > mem_avail) &&										(target->virtual_width < (1600 - crtc_mask)))										*acc_mode = false;									else										video_pitch = 1600;								}		}	}	if (!*acc_mode)		video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);	LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n",														video_pitch, target->space)); 	if (target->virtual_width != video_pitch)		LOG(2,("INIT: effective mode slopspace is %d pixels\n", 											(video_pitch - target->virtual_width)));	/* now calculate bytes_per_row for this mode */	*bytes_per_row = video_pitch * (depth >> 3);	return B_OK;}