📄 fgl.c
字号:
/**
* Samsung Project
* Copyright (c) 2007-2008 Mobile XG, Samsung Electronics, Inc.
* All right reserved.
*
* This software is the confidential and proprietary information
* of Samsung Electronics Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Samsung Electronics.
*/
/**
* @file fgl.c
* @brief This is the global-register-setting file.
* @author Thomas, Kim
* @version 1.5
*/
#include <stdlib.h>
#include <string.h>
#include "fgl.h"
/*****************************************************************************
*
* Control Block
*
*****************************************************************************/
FGLAPI fgl_pipeline_status ( uint32 * flag )
{
READREGP(FGGB_PIPESTATE, *flag);
}
FGLAPI fgl_pipeline_isempty ( const uint32 flag )
{
volatile uint32 rval = 0;
do
{
READREGP(FGGB_PIPESTATE, rval);
} while(rval & flag);
}
FGLAPI fgl_flush_cache ( const uint32 flag )
{
volatile uint32 rval = 0;
WRITEREG(FGGB_CACHECTL, flag);
do
{
READREGP(FGGB_CACHECTL, rval);
} while(rval & flag);
}
FGLAPI fgl_soft_reset ( void )
{
volatile uint32 i;
WRITEREG(FGGB_RESET, 1);
/* delay */
for(i = 0; i < 50; i++)
{
#if TARGET_PLATFORM == LINUX
__asm__ __volatile__ ("nop");
#elif TARGET_PLATFORM == WINCE
__asm ("nop");
#elif TARGET_PLATFORM == FIRMWARE
__asm {nop}
#endif
}
WRITEREG(FGGB_RESET, 0);
}
FGLAPI fgl_version ( uint32 * major, uint32 * minor )
{
uint32 ver;
READREGP(FGGB_VERSION, ver);
*major = ((ver & 0xFF000000) >> 24);
*minor = (ver & 0xFFFFFF);
}
FGLAPI fgl_clear_pending_int ( void )
{
WRITEREG(FGGB_INTPENDING, 0x0);
}
FGLAPI fgl_get_pending_int ( uint32 * state )
{
READREGP(FGGB_INTPENDING, *state);
}
FGLAPI fgl_enable_int ( void )
{
WRITEREG(FGGB_INTMASK, 1);
}
FGLAPI fgl_disable_int ( void )
{
WRITEREG(FGGB_INTMASK, 0);
}
/*
* Specifies the related block to generate interrupt.
*/
FGLAPI fgl_interrupt_mask ( const uint32 flag )
{
WRITEREG(FGGB_PIPEMASK, flag);
}
FGLAPI fgl_interrupt_target ( const uint32 flag )
{
WRITEREG(FGGB_PIPETGTSTATE, (flag & PSF_ALL));
}
/*
* Has been preserved first pipeline state when interrupts occured.
*/
FGLAPI fgl_interrupt_status ( uint32 * status )
{
READREGP(FGGB_PIPEINTSTATE, *status);
}
/*****************************************************************************
*
* Host Interface Block
*
*****************************************************************************/
FGLAPI fgl_get_empty_slots ( uint32 * slots )
{
READREGP(FGHI_DWSPACE, *slots);
}
FGLAPI fgl_transfer_fifo ( void * src, uint32 size )
{
#if 1
uint32 space = 0, nth = 0;
unsigned char *ptr = src, bits[4];
int32 i, diff;
do {
if(space == 0)
{
do {
READREGP(FGHI_DWSPACE, space);
} while(!space);
}
diff = size - nth;
if(diff < 4)
{
bits[0] = bits[1] = bits[2] = bits[3] = 0x00;
for(i=0; i<diff; i++)
bits[i] = ptr[nth++];
WRITEREG(FGHI_DWENTRY, *((uint32 *)bits));
space --;
}
else
{
WRITEREG(FGHI_DWENTRY, *((uint32 *)&(ptr[nth])));
space --;
nth += 4;
}
} while(nth < size);
#else
//unsigned int *pdst_port = FGHI_FIFO_ENTRY;
unsigned int offset = (unsigned int)psrc_data & 0x0000001F;
unsigned int alloc_size = 0;
if(psrc_data == FGL_NULL || size == 0)
{
// For debug
//WRITEREG(0x00000104, 0xFFFFFFFF);
return;
}
do
{
do
{
alloc_size = fglSysReservePortAlloc(size, 1);
} while (alloc_size == 0);
/* Write out dwords until we reach 32-byte alignment */
if (offset > 0)
{
unsigned int before_align = 8 - (offset >> 2);
if (before_align > alloc_size)
{
before_align = alloc_size;
alloc_size = 0;
}
else
{
alloc_size -= before_align;
}
while (before_align-- > 0)
{
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
size --;
}
offset = (unsigned int)psrc_data & 0x0000001F;
}
/* This works on aligned data */
while (alloc_size & 0xFFFFFFF8)
{
#if TARGET_PLATFORM == WIN32_VIP
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
WRITEREG(FGHI_FIFO_ENTRY, *(psrc_data++));
#elif TARGET_PLATFORM == FPGA_BOARD
unsigned int a0, a1, a2, a3, a4, a5, a6, a7;
__asm
{
LDMIA psrc_data!,{a0, a1, a2, a3, a4, a5, a6, a7}
STMIA FGHI_FIFO_ENTRY, {a0, a1, a2, a3, a4, a5, a6, a7}
}
#endif
alloc_size -= 8;
size -= 8;
}
} while (size & 0xFFFFFFF8);
/* Write out the last < 8 dwords */
while (size-- > 0)
{
WRITEREG(FGHI_FIFO_ENTRY, *psrc_data);
++psrc_data;
}
#endif
}
/*
* In case used the point sprite mode, the number of vertex shader output must be plus one.
*/
FGLAPI fgl_host_interface ( void * hostinfo )
{
struct host_interface_info * p;
ASSERT( hostinfo != 0 );
p = (struct host_interface_info *)hostinfo;
ASSERT(p->vertex_shader_out < 16); // cheolkyoo, kim must be checked
WRITEREG(FGHI_CONTROL, ((p->vertex_shader_out) | (((p->vtxcache)?1:0) << 4) |
(((p->autoinc)?1:0) << 16) | (p->idx_type) << 24 | (((p->vtxbuf)?1:0)<< 31)));
}
FGLAPI fgl_index_offset ( uint32 offset )
{
WRITEREG(FGHI_IDXOFFSET, offset);
}
FGLAPI fgl_attribute ( const uint32 count, void * attrib )
{
uint32 i;
struct attribute_info * p;
ASSERT( attrib != 0 );
p = (struct attribute_info *)attrib;
ASSERT( count < 11 );
ASSERT( p->component > 0 && p->component < 5 );
#if 1
for (i = 0; i < (count - 1); i++)
{
WRITEREG((FGHI_ATTRIB + i * 4), (p[i].x | (p[i].y << 2) | (p[i].z << 4) | (p[i].w << 6) |
((p[i].component - 1) << 8) | (p[i].dtype << 12)));
}
WRITEREG((FGHI_ATTRIB + i * 4), ((0x80000000) | (p[i].x) | (p[i].y << 2) | (p[i].z << 4) | (p[i].w << 6) |
((p[i].component - 1) << 8) | (p[i].dtype << 12)));
#endif
}
FGLAPI fgl_transfer_vtxbuf ( void * vbdata, uint32 words )
{
// TODO : write code using ARM assembler
#if 1
uint32 i;
for (i = (words >> 11); i != 0; i--)
{
memcpy((void *)FGHI_VBDATA, vbdata, (FGHI_VBDATA_BURST_WSIZE * 4));
vbdata = (uint32 *)vbdata + FGHI_VBDATA_BURST_WSIZE;
}
words = (words & (FGHI_VBDATA_BURST_WSIZE - 1));
if (words)
memcpy((void *)FGHI_VBDATA, vbdata, (words * 4));
#endif
#if 0
uint32 i;
for (i = (words >> 2); i != 0; i--)
{
WRITEREG(FGHI_VBDATA, *(vbdata++));
WRITEREG(FGHI_VBDATA, *(vbdata++));
WRITEREG(FGHI_VBDATA, *(vbdata++));
WRITEREG(FGHI_VBDATA, *(vbdata++));
}
for (i = (words & 3); i != 0; i--)
WRITEREG(FGHI_VBDATA, *(vbdata++));
#endif
#if 0
do
{
WRITEREG(FGHI_VBDATA, *(vbdata++));
} while (--words != 0)
#endif
}
FGLAPI fgl_vtxbuf_attribute ( uint32 index, uint32 stride, uint32 count, uint32 base )
{
ASSERT(index < 10);
WRITEREG((FGHI_ATTRIB_VBCTRL + (index << 2)), (count | (stride << 24)));
WRITEREG((FGHI_ATTRIB_VBBASE + (index << 2)), base);
}
/*****************************************************************************
*
* Primitive Engine
*
*****************************************************************************/
FGLAPI fgl_vertex ( void * context )
{
uint32 reg_val = 0;
struct vertex_context * pctx = (struct vertex_context *)context;
ASSERT(pctx->vertex_shader_out < 10);
reg_val = (( pctx->type << 19) | (pctx->vertex_shader_out << 10));
if( pctx->flat_color_pos )
{
reg_val |= ( (1 << 9) | (pctx->flat_color_pos & 0x1FF));
}
WRITEREG(FGPE_VERTEX_CONTEXT, reg_val);
}
FGLAPI fgl_viewport ( void * viewport )
{
struct viewport_info vpdata;
float half_x = 0.0;
float halp_y = 0.0;
float center_x = 0.0;
float center_y = 0.0;
memcpy((void *)&vpdata, viewport, sizeof(struct viewport_info));
half_x = (float)vpdata.width * 0.5;
halp_y = (float)vpdata.height * 0.5;
center_x = (float)vpdata.x + half_x;
center_y = 0.0;
if (vpdata.flip) {
center_y = (float)(vpdata.win_height - vpdata.y) - halp_y;
halp_y *= (-1.f);
} else {
center_y = (float)(vpdata.y + halp_y);
}
WRITEREGF(FGPE_VIEWPORT_OX, center_x);
WRITEREGF(FGPE_VIEWPORT_OY, center_y);
WRITEREGF(FGPE_VIEWPORT_HALF_PX, half_x);
WRITEREGF(FGPE_VIEWPORT_HALF_PY, halp_y);
}
FGLAPI fgl_depth_range ( const float near, const float far)
{
ASSERT((near >= 0.0) && (near <= 1.0));
ASSERT((far >= 0.0) && (far <= 1.0));
WRITEREGF(FGPE_DEPTHRANGE_HALF_F_SUB_N, ((far - near) * 0.5));
WRITEREGF(FGPE_DEPTHRANGE_HALF_F_ADD_N, ((far + near) * 0.5));
}
/*****************************************************************************
*
* Rasterizer
*
*****************************************************************************/
/*
* controls whether pixel is sampled at the center or corner.
*/
FGLAPI fgl_pixel_sampos ( const fglenum pos )
{
WRITEREG(FGRA_PIXSAMP, pos);
}
FGLAPI fgl_disable_doffset ( void )
{
WRITEREG(FGRA_DOFFEN, 0);
}
FGLAPI fgl_doffset ( const float factor, const float units)
{
WRITEREGF(FGRA_DOFFFACTOR, factor);
WRITEREGF(FGRA_DOFFUNITS, units);
}
FGLAPI fgl_doffset_r ( const float rval )
{
WRITEREGF(FGRA_DOFFRIN, rval);
}
FGLAPI fgl_disable_cullface ( void )
{
WRITEREG(FGRA_BFCULL, 0);
}
FGLAPI fgl_cull_face ( const bool clockwise, const fglenum mode )
{
if (clockwise)
WRITEREG(FGRA_BFCULL, (0xC | (mode & 0x3)));
else
WRITEREG(FGRA_BFCULL, (0x8 | (mode & 0x3)));
}
/*
* Sets the x, y clipping plan.
*/
FGLAPI fgl_clip_plan ( const uint32 left, const uint32 right, const uint32 bottom, const uint32 top )
{
ASSERT((left < 4096) && (right < 4096));
ASSERT((bottom < 4096) && (top < 4096));
WRITEREG(FGRA_XCLIP, ((right << 16) | left));
WRITEREG(FGRA_YCLIP, ((top << 16) | bottom));
}
/*
* Generate the LOD coefficent value that Fragment Shader calculate the LOD value for texturing.
*/
FGLAPI fgl_lodctrl ( const uint32 lod )
{
ASSERT(!(lod & 0xFF000000));
WRITEREG(FGRA_LODCTL, lod);
}
FGLAPI fgl_point_width ( const float width )
{
WRITEREGF(FGRA_PWIDTH, width);
}
FGLAPI fgl_psize_minmax ( const float min, const float max )
{
ASSERT((min >= 0.0) && (max <= 2048.0));
WRITEREGF(FGRA_PSIZE_MIN, min);
WRITEREGF(FGRA_PSIZE_MAX, max);
}
/*
* Used only in point sprite rendering.
* Only one bit chooses generated texture coordinate for point sprite.
* Alway replace coord must be set last position of attributes .
*/
FGLAPI fgl_replace_coord( const uint32 coord )
{
ASSERT(coord < 8);
WRITEREG(FGRA_COORDREPLACE, (1 << coord));
}
FGLAPI fgl_line_width ( const float width )
{
WRITEREGF(FGRA_LWIDTH, width);
}
/*****************************************************************************
*
* Texture Units Register-level API
*
*****************************************************************************/
static void _gen_mipmap_offset ( const fglenum format, uint32 width, uint32 height, uint32 * offset )
{
uint32 i = 0;
uint32 bigger = 0;
uint32 tmp = 0;
uint32 texsize = width * height;
switch(format)
{
case TFMT_ARGB1555 :
case TFMT_RGB565 :
case TFMT_ARGB4444 :
case TFMT_DEPTH24 :
case TFMT_IA88 :
case TFMT_I8 :
case TFMT_ARGB8888 :
case TFMT_1BPP :
case TFMT_2BPP :
case TFMT_4BPP :
case TFMT_8BPP :
{
offset[0] = texsize;
bigger = width > height ? width : height;
bigger >>= 1;
for( i = 1; (bigger > 0 && i < 10); i++) {
width = (width <= 1) ? 1 : (width >> 1);
height = (height <= 1) ? 1 : (height >> 1);
texsize += width * height;
offset[i] = texsize;
bigger >>= 1;
}
}
break;
case TFMT_S3TC :
{
if((texsize == 4) || (texsize == 1)) {
offset[0] = 16;
break;
} else {
offset[0] = texsize;
}
bigger = width > height ? width : height;
bigger >>= 1;
for( i = 1; (bigger > 0 && i < 10); i++) {
width = (width <= 1) ? 1 : (width >> 1);
height = (height <= 1) ? 1 : (height >> 1);
tmp = width * height;
if((tmp == 4) || (tmp == 1)) {
texsize += 16;
} else {
texsize += tmp;
}
bigger >>= 1;
offset[i] = texsize;
}
}
break;
case TFMT_Y1VY0U :
case TFMT_VY1UY0 :
case TFMT_Y1UY0V :
case TFMT_UY1VY0 :
{
if(texsize == 1) {
offset[0] = 2;
break;
} else {
offset[0] = texsize;
}
bigger = width > height ? width : height;
bigger >>= 1;
for( i = 0; (bigger > 0 && i < 10); i++) {
width = (width <= 1) ? 1 : (width >> 1);
height = (height <= 1) ? 1 : (height >> 1);
tmp = width * height;
if((tmp == 1)) {
texsize += 2;
} else {
texsize += tmp;
}
bigger >>= 1;
offset[i] = texsize;
}
}
break;
default :
ASSERT(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -