⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cim_gp.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
 /*
  * <LIC_AMD_STD>
  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
  * </LIC_AMD_STD>
  *
  * <CTL_AMD_STD>
  * </CTL_AMD_STD>
  *
  * <DOC_AMD_STD>
  * Cimarron graphics processor routines.  These routines program the graphics
  * hardware using the graphics command buffer.
  * </DOC_AMD_STD>
  *
  */

/*---------------------*/
/* CIMARRON GP GLOBALS */
/*---------------------*/

CIMARRON_STATIC unsigned long gp3_bpp         = 0;
CIMARRON_STATIC unsigned long gp3_ch3_bpp     = 0;
CIMARRON_STATIC unsigned long gp3_pat_origin  = 0;
CIMARRON_STATIC unsigned long gp3_buffer_lead = 0;
CIMARRON_STATIC unsigned long gp3_cmd_header;
CIMARRON_STATIC unsigned long gp3_cmd_top;
CIMARRON_STATIC unsigned long gp3_cmd_bottom;
CIMARRON_STATIC unsigned long gp3_cmd_current;
CIMARRON_STATIC unsigned long gp3_cmd_next;
CIMARRON_STATIC unsigned long gp3_blt_mode;
CIMARRON_STATIC unsigned long gp3_vec_mode;
CIMARRON_STATIC unsigned long gp3_raster_mode;
CIMARRON_STATIC unsigned long gp3_pix_shift;
CIMARRON_STATIC unsigned long gp3_ch3_pat;
CIMARRON_STATIC unsigned long gp3_blt;
CIMARRON_STATIC unsigned long gp3_blt_flags;
CIMARRON_STATIC unsigned long gp3_src_stride;
CIMARRON_STATIC unsigned long gp3_dst_stride;
CIMARRON_STATIC unsigned long gp3_src_format;
CIMARRON_STATIC unsigned long gp3_src_pix_shift;
CIMARRON_STATIC unsigned long gp3_pat_format;
CIMARRON_STATIC unsigned long gp3_pat_pix_shift;
CIMARRON_STATIC unsigned long gp3_fb_base;
CIMARRON_STATIC unsigned long gp3_vector_pattern_color;
CIMARRON_STATIC unsigned long gp3_scratch_base;
CIMARRON_STATIC unsigned long gp3_base_register;
CIMARRON_STATIC unsigned long gp3_vec_pat;

/*---------------------------------------------------------------------------
 * gp_set_limit_on_buffer_lead
 *
 * This routine is used to specify the maximum number of bytes in the command
 * buffer by which software can lead the graphics processor.  When declaring
 * a BLT with the CIMGP_BLTFLAGS_LIMITBUFFER flag set, Cimarron will wait until
 * the command buffer read and write pointers differ by no more than 'lead'
 * bytes.  This can be useful to limit the time lag possible when creating a
 * command buffer full of simple BLT commands.
 *-------------------------------------------------------------------------*/

void gp_set_limit_on_buffer_lead (unsigned long lead)
{	
	gp3_buffer_lead = lead;
}

/*---------------------------------------------------------------------------
 * gp_set_command_buffer_base
 *
 * This routine is used to program the command buffer region in physical
 * memory.  The command buffer start address must be 1MB aligned. start and
 * stop refer to endpoints within the associated 16MB region.  Command buffers
 * larger than 16MB are not supported.
 *-------------------------------------------------------------------------*/

void gp_set_command_buffer_base (unsigned long address, unsigned long start,
	unsigned long stop)
{	
	Q_WORD msr_value;

	/* WAIT FOR IDLE */
	/* Obviously, we cannot change the command buffer pointer while the GP */
	/* is currently fetching commands.                                     */

	gp_wait_until_idle();

    /* WRITE THE COMMAND BUFFER BASE */

	msr_read64 (MSR_DEVICE_GEODELX_GP, MSR_GEODELINK_CONFIG, &msr_value);
	msr_value.low &= 0xF000FFFF;
	msr_value.low |= (address >> 4) & 0x0FFF0000;
	msr_write64 (MSR_DEVICE_GEODELX_GP, MSR_GEODELINK_CONFIG, &msr_value);

    /* WRITE THE BASE OFFSETS */
	/* We also reset the write and read pointers.  The hardware will */
	/* automatically update the write pointer when the read pointer  */
	/* is updated to prevent the hardware from getting confused when */
	/* initializing a new command buffer.                            */

	WRITE_GP32 (GP3_CMD_TOP, start);
	WRITE_GP32 (GP3_CMD_BOT, stop);
	WRITE_GP32 (GP3_CMD_READ, start);

    /* SAVE THE BASE ADDRESSES */
	/* These are used to determine the appropriate wrap point. */

	gp3_cmd_current = gp3_cmd_top = start;
	gp3_cmd_bottom  = stop;
}

/*---------------------------------------------------------------------------
 * gp_set_frame_buffer_base
 *
 * This routine is used to program the base address of the frame buffer in
 * physical memory.  The frame buffer address must be 16MB aligned.  Cimarron
 * tracks the base address because the maximum frame buffer size may exceed
 * 16MB. Any primitive will thus program the corresponding 16MB region into all
 * base offset registers as well as program the offset into the 16MB region.
 * The size parameter is provided to allow Cimarron to claim the last 1MB of
 * space to be used as a scratch area for workarounds or expanded functionality.
 *-------------------------------------------------------------------------*/

void gp_set_frame_buffer_base (unsigned long address, unsigned long size)
{	
    gp3_scratch_base = size - GP3_SCRATCH_BUFFER_SIZE;
	gp3_fb_base = address >> 24;
    gp3_base_register = (gp3_fb_base << 24) | (gp3_fb_base << 14) | (gp3_fb_base << 4);
    WRITE_GP32 (GP3_BASE_OFFSET, gp3_base_register);
}

/*---------------------------------------------------------------------------
 * gp_set_bpp
 *
 * This routine sets the output BPP of the GP.  The BPP used by the GP does
 * not have to match the display BPP, but that is usually the case.  The
 * supported BPP values are as follows:
 *
 *    8  - palettized 8BPP
 *    12 - 4:4:4:4
 *    15 - 1:5:5:5
 *    16 - 0:5:6:5
 *    32 - 8:8:8:8
 *-------------------------------------------------------------------------*/

void gp_set_bpp (int bpp)
{
	/* STORE BPP */
	/* The bpp is not updated until the next call to gp_set_raster_mode. */
	/* This allows the gp_set_bpp call to happen outside of a BLT.  It   */
	/* also implies that no registers need be written in this routine.   */
	
	switch(bpp)
	{
		case 8:	
			gp3_bpp       = GP3_RM_BPPFMT_332;
			gp3_ch3_bpp   = GP3_CH3_SRC_3_3_2;
			gp3_pix_shift = 0;
			break;
		case 12:
			gp3_bpp       = GP3_RM_BPPFMT_4444;
			gp3_ch3_bpp   = GP3_CH3_SRC_4_4_4_4;
			gp3_pix_shift = 1;
			break;
		case 15:
			gp3_bpp       = GP3_RM_BPPFMT_1555;
			gp3_ch3_bpp   = GP3_CH3_SRC_1_5_5_5;
			gp3_pix_shift = 1;
			break;
		case 16:
			gp3_bpp       = GP3_RM_BPPFMT_565;
			gp3_ch3_bpp   = GP3_CH3_SRC_0_5_6_5;
			gp3_pix_shift = 1;
			break;
        case 24:
        case 32:
			gp3_bpp       = GP3_RM_BPPFMT_8888;
			gp3_ch3_bpp   = GP3_CH3_SRC_8_8_8_8;
			gp3_pix_shift = 2;
			break;
		default:
			gp3_bpp       = GP3_RM_BPPFMT_332;
			gp3_ch3_bpp   = GP3_CH3_SRC_3_3_2;
			gp3_pix_shift = 0;
			break;
	}
}

/*---------------------------------------------------------------------------
 * gp_declare_blt
 *
 * This routine is used to prepare for a 2D BLT.  Its primary function
 * is to verify that enough room is available in the command buffer
 * to hold a BLT command.  This command can be called multiple times if
 * necessary.  For example, if a function calls this routine on entry, but
 * later realizes that a LUT load command must be executed before the BLT,
 * the application could call gp_set_color_pattern and then call
 * gp_declare_blt to declare the BLT.  This is possible because the hardware
 * buffer pointer is not updated until a new BLT is actually executed.  An
 * application must take care not to call any routines that perform a buffer
 * command, (such as gp_set_color_pattern) between gp_declare_blt and the
 * routines used to program the BLT parameters.  In addition to checking for
 * available space, this routine also performs the following actions:
 *    - Sets the wrap bit if this BLT will pass close to the end of the buffer.
 *    - Writes the command header.
 *
 * The available flags are defined as follows:
 *   0x01 - Preserve the LUT
 *   0x02 - Preserve the color pattern.
 *   0x04 - Enable prefetch.
 *-------------------------------------------------------------------------*/

void gp_declare_blt (unsigned long flags)
{	
	unsigned long temp;

	gp3_blt = 1;
	gp3_blt_flags = flags;

	/* SET ADDRESS OF NEXT COMMAND */
	/* A summary of the command buffer logic is as follows:           */
	/*  - If after a basic BLT we will not have room for the largest  */
	/*    command (a full line of host source data), we set the wrap  */
	/*    bit.  This will waste up to a whopping 8K of command buffer */
	/*    space, but it simplifies the logic for all commands.        */
	/* -  If we are wrapping, we have extra logic to ensure that we   */
	/*    don't skip over the current GP read pointer.                */

    gp3_cmd_next = gp3_cmd_current + GP3_BLT_COMMAND_SIZE;

	/* CHECK WRAP CONDITION */

	if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
	{
		gp3_cmd_next   = gp3_cmd_top;
		gp3_cmd_header = GP3_BLT_HDR_TYPE | GP3_BLT_HDR_WRAP;

		/* WAIT FOR HARDWARE */
		/* When wrapping, we must take steps to ensure that we do not    */
		/* wrap over the current hardware read pointer.  We do this by   */
		/* verifying that the hardware is not between us and the end of  */
		/* the command buffer.  We also have a special case to make sure */
		/* that the hardware is not currently reading the top of the     */
		/* command buffer.                                               */

		GP3_WAIT_WRAP(temp);
	}
	else
	{
		gp3_cmd_header = GP3_BLT_HDR_TYPE;

		/* WAIT FOR AVAILABLE SPACE */

		GP3_WAIT_PRIMITIVE(temp);
	}

    if (flags & CIMGP_BLTFLAGS_LIMITBUFFER)
    {
        while (1)
        {
            temp = READ_GP32 (GP3_CMD_READ);
            if (((gp3_cmd_current >= temp) && ((gp3_cmd_current - temp) <= gp3_buffer_lead)) ||
                ((gp3_cmd_current <  temp) && ((gp3_cmd_current + (gp3_cmd_bottom - temp)) <= gp3_buffer_lead)))
            {
                break;
            }
        }
    }

	/* SET THE CURRENT BUFFER POINTER */
	/* We initialize a pointer to the current buffer base to avoid an */
	/* extra addition for every buffer write.                         */

	cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;

    /* SET THE HAZARD BIT */

    if (flags & CIMGP_BLTFLAGS_HAZARD)
        gp3_cmd_header |= GP3_BLT_HDR_HAZARD_ENABLE;
}

/*---------------------------------------------------------------------------
 * gp_declare_vector
 *
 * This routine is used to prepare for a 2D vector.  It has no other function
 * except to verify that enough room is available in the command buffer
 * to hold a vector command.  The same rules that apply to BLTs apply to
 * vectors. (See the documentation for gp_declare_blt).
 *-------------------------------------------------------------------------*/

void gp_declare_vector (unsigned long flags)
{
	unsigned long temp;

	gp3_blt = 0;
    gp3_blt_flags = flags;
	
	/* SET ADDRESS OF NEXT COMMAND                            */
	/* The logic to force a wrap during a vector is identical */
	/* to the BLT logic.                                      */

    /* ALLOCATE SPACE FOR AN ADDITIONAL VECTOR TO CLEAR THE BYTE ENABLES */

    gp3_cmd_next = gp3_cmd_current + GP3_VECTOR_COMMAND_SIZE + GP3_VECTOR_COMMAND_SIZE + 32;

	/* CHECK WRAP CONDITION */

	if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
	{
		gp3_cmd_next   = gp3_cmd_top;
		gp3_cmd_header = GP3_VEC_HDR_TYPE | GP3_VEC_HDR_WRAP;

		/* CHECK WRAP CONDITION */

		GP3_WAIT_WRAP(temp);
	}
	else
	{
		gp3_cmd_header = GP3_VEC_HDR_TYPE;

		/* WAIT FOR AVAILABLE SPACE */

		GP3_WAIT_PRIMITIVE(temp);

        gp3_cmd_next -= GP3_VECTOR_COMMAND_SIZE + 32;
	}

    if (flags & CIMGP_BLTFLAGS_LIMITBUFFER)
    {
        while (1)
        {
            temp = READ_GP32 (GP3_CMD_READ);
            if (((gp3_cmd_current >= temp) && ((gp3_cmd_current - temp) <= gp3_buffer_lead)) ||
                ((gp3_cmd_current <  temp) && ((gp3_cmd_current + (gp3_cmd_bottom - temp)) <= gp3_buffer_lead)))
            {
                break;
            }
        }
    }

	cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;

    /* SET THE HAZARD BIT */

    if (flags & CIMGP_BLTFLAGS_HAZARD)
        gp3_cmd_header |= GP3_VEC_HDR_HAZARD_ENABLE;
}

/*---------------------------------------------------------------------------
 * gp_write_parameters
 *
 * This routine is called to write all recent parameters to the hardware.
 * This routine is necessary for any implementation that performs the setup
 * for a BLT separate from the actual BLT.  An example would be a driver
 * that prepares for multiple pattern fills by programming the ROP,
 * pattern color and destination stride.  The driver might then perform
 * repeated pattern fills with minimal effort.
 *-------------------------------------------------------------------------*/

void gp_write_parameters (void)
{
	/* WRITE THE COMMAND HEADER */
	/* Command header is at offset 0 for BLTs and vectors */
	
	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
	
	/* INCREMENT THE CURRENT WRITE POINTER */

	gp3_cmd_current = gp3_cmd_next;

	/* UPDATE THE GP WRITE POINTER */

	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_current);
}

/*---------------------------------------------------------------------------
 * gp_set_raster_operation
 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -