📄 radeon_swtcl.c
字号:
fprintf(stderr, "radeon_render.c: prim %s %d..%d\n", _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK), start, start+length); if (length) tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim ); } tnl->Driver.Render.Finish( ctx ); return GL_FALSE; /* finished the pipe */}const struct tnl_pipeline_stage _radeon_render_stage ={ "radeon render", NULL, NULL, NULL, NULL, radeon_run_render /* run */};/**************************************************************************/static const GLuint reduced_hw_prim[GL_POLYGON+1] = { RADEON_CP_VC_CNTL_PRIM_TYPE_POINT, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST};static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim );static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim );static void radeonResetLineStipple( GLcontext *ctx );/*********************************************************************** * Emit primitives as inline vertices * ***********************************************************************/#undef LOCAL_VARS#undef ALLOC_VERTS#define CTX_ARG radeonContextPtr rmesa#define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size#define ALLOC_VERTS( n, size ) radeonAllocDmaLowVerts( rmesa, n, (size) * 4 )#undef LOCAL_VARS#define LOCAL_VARS \ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ const char *radeonverts = (char *)rmesa->swtcl.verts;#define VERT(x) (radeonVertex *)(radeonverts + ((x) * (vertsize) * sizeof(int)))#define VERTEX radeonVertex #undef TAG#define TAG(x) radeon_##x#include "tnl_dd/t_dd_triemit.h"/*********************************************************************** * Macros for t_dd_tritmp.h to draw basic primitives * ***********************************************************************/#define QUAD( a, b, c, d ) radeon_quad( rmesa, a, b, c, d )#define TRI( a, b, c ) radeon_triangle( rmesa, a, b, c )#define LINE( a, b ) radeon_line( rmesa, a, b )#define POINT( a ) radeon_point( rmesa, a )/*********************************************************************** * Build render functions from dd templates * ***********************************************************************/#define RADEON_TWOSIDE_BIT 0x01#define RADEON_UNFILLED_BIT 0x02#define RADEON_MAX_TRIFUNC 0x04static struct { tnl_points_func points; tnl_line_func line; tnl_triangle_func triangle; tnl_quad_func quad;} rast_tab[RADEON_MAX_TRIFUNC];#define DO_FALLBACK 0#define DO_OFFSET 0#define DO_UNFILLED (IND & RADEON_UNFILLED_BIT)#define DO_TWOSIDE (IND & RADEON_TWOSIDE_BIT)#define DO_FLAT 0#define DO_TRI 1#define DO_QUAD 1#define DO_LINE 1#define DO_POINTS 1#define DO_FULL_QUAD 1#define HAVE_RGBA 1#define HAVE_SPEC 1#define HAVE_BACK_COLORS 0#define HAVE_HW_FLATSHADE 1#define TAB rast_tab#define DEPTH_SCALE 1.0#define UNFILLED_TRI unfilled_tri#define UNFILLED_QUAD unfilled_quad#define VERT_X(_v) _v->v.x#define VERT_Y(_v) _v->v.y#define VERT_Z(_v) _v->v.z#define AREA_IS_CCW( a ) (a < 0)#define GET_VERTEX(e) (rmesa->swtcl.verts + ((e) * rmesa->swtcl.vertex_size * sizeof(int)))#define VERT_SET_RGBA( v, c ) \do { \ radeon_color_t *color = (radeon_color_t *)&((v)->ui[coloroffset]); \ UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \ UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \ UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \ UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \} while (0)#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]#define VERT_SET_SPEC( v, c ) \do { \ if (specoffset) { \ radeon_color_t *spec = (radeon_color_t *)&((v)->ui[specoffset]); \ UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]); \ UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]); \ UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]); \ } \} while (0)#define VERT_COPY_SPEC( v0, v1 ) \do { \ if (specoffset) { \ radeon_color_t *spec0 = (radeon_color_t *)&((v0)->ui[specoffset]); \ radeon_color_t *spec1 = (radeon_color_t *)&((v1)->ui[specoffset]); \ spec0->red = spec1->red; \ spec0->green = spec1->green; \ spec0->blue = spec1->blue; \ } \} while (0)/* These don't need LE32_TO_CPU() as they used to save and restore * colors which are already in the correct format. */#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]#undef LOCAL_VARS#undef TAG#undef INIT#define LOCAL_VARS(n) \ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ GLuint color[n], spec[n]; \ GLuint coloroffset = rmesa->swtcl.coloroffset; \ GLuint specoffset = rmesa->swtcl.specoffset; \ (void) color; (void) spec; (void) coloroffset; (void) specoffset;/*********************************************************************** * Helpers for rendering unfilled primitives * ***********************************************************************/#define RASTERIZE(x) radeonRasterPrimitive( ctx, reduced_hw_prim[x] )#define RENDER_PRIMITIVE rmesa->swtcl.render_primitive#undef TAG#define TAG(x) x#include "tnl_dd/t_dd_unfilled.h"#undef IND/*********************************************************************** * Generate GL render functions * ***********************************************************************/#define IND (0)#define TAG(x) x#include "tnl_dd/t_dd_tritmp.h"#define IND (RADEON_TWOSIDE_BIT)#define TAG(x) x##_twoside#include "tnl_dd/t_dd_tritmp.h"#define IND (RADEON_UNFILLED_BIT)#define TAG(x) x##_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (RADEON_TWOSIDE_BIT|RADEON_UNFILLED_BIT)#define TAG(x) x##_twoside_unfilled#include "tnl_dd/t_dd_tritmp.h"static void init_rast_tab( void ){ init(); init_twoside(); init_unfilled(); init_twoside_unfilled();}/**********************************************************************//* Render unclipped begin/end objects *//**********************************************************************/#define RENDER_POINTS( start, count ) \ for ( ; start < count ; start++) \ radeon_point( rmesa, VERT(start) )#define RENDER_LINE( v0, v1 ) \ radeon_line( rmesa, VERT(v0), VERT(v1) )#define RENDER_TRI( v0, v1, v2 ) \ radeon_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )#define RENDER_QUAD( v0, v1, v2, v3 ) \ radeon_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )#undef INIT#define INIT(x) do { \ radeonRenderPrimitive( ctx, x ); \} while (0)#undef LOCAL_VARS#define LOCAL_VARS \ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ const GLuint vertsize = rmesa->swtcl.vertex_size; \ const char *radeonverts = (char *)rmesa->swtcl.verts; \ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ const GLboolean stipple = ctx->Line.StippleFlag; \ (void) elt; (void) stipple;#define RESET_STIPPLE if ( stipple ) radeonResetLineStipple( ctx );#define RESET_OCCLUSION#define PRESERVE_VB_DEFS#define ELT(x) (x)#define TAG(x) radeon_##x##_verts#include "tnl/t_vb_rendertmp.h"#undef ELT#undef TAG#define TAG(x) radeon_##x##_elts#define ELT(x) elt[x]#include "tnl/t_vb_rendertmp.h"/**********************************************************************//* Choose render functions *//**********************************************************************/void radeonChooseRenderState( GLcontext *ctx ){ TNLcontext *tnl = TNL_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint index = 0; GLuint flags = ctx->_TriangleCaps; if (!rmesa->TclFallback || rmesa->Fallback) return; if (flags & DD_TRI_LIGHT_TWOSIDE) index |= RADEON_TWOSIDE_BIT; if (flags & DD_TRI_UNFILLED) index |= RADEON_UNFILLED_BIT; if (index != rmesa->swtcl.RenderIndex) { tnl->Driver.Render.Points = rast_tab[index].points; tnl->Driver.Render.Line = rast_tab[index].line; tnl->Driver.Render.ClippedLine = rast_tab[index].line; tnl->Driver.Render.Triangle = rast_tab[index].triangle; tnl->Driver.Render.Quad = rast_tab[index].quad; if (index == 0) { tnl->Driver.Render.PrimTabVerts = radeon_render_tab_verts; tnl->Driver.Render.PrimTabElts = radeon_render_tab_elts; tnl->Driver.Render.ClippedPolygon = radeon_fast_clipped_poly; } else { tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; } rmesa->swtcl.RenderIndex = index; }}/**********************************************************************//* High level hooks for t_vb_render.c *//**********************************************************************/static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if (rmesa->swtcl.hw_primitive != hwprim) { RADEON_NEWPRIM( rmesa ); rmesa->swtcl.hw_primitive = hwprim; }}static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); rmesa->swtcl.render_primitive = prim; if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED)) radeonRasterPrimitive( ctx, reduced_hw_prim[prim] );}static void radeonRenderFinish( GLcontext *ctx ){}static void radeonResetLineStipple( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); RADEON_STATECHANGE( rmesa, lin );}/**********************************************************************//* Transition to/from hardware rasterization. *//**********************************************************************/static const char * const fallbackStrings[] = { "Texture mode", "glDrawBuffer(GL_FRONT_AND_BACK)", "glEnable(GL_STENCIL) without hw stencil buffer", "glRenderMode(selection or feedback)", "glBlendEquation", "glBlendFunc", "RADEON_NO_RAST", "Mixing GL_CLAMP_TO_BORDER and GL_CLAMP (or GL_MIRROR_CLAMP_ATI)"};static const char *getFallbackString(GLuint bit){ int i = 0; while (bit > 1) { i++; bit >>= 1; } return fallbackStrings[i];}void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint oldfallback = rmesa->Fallback; if (mode) { rmesa->Fallback |= bit; if (oldfallback == 0) { RADEON_FIREVERTICES( rmesa ); TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_TRUE ); _swsetup_Wakeup( ctx ); rmesa->swtcl.RenderIndex = ~0; if (RADEON_DEBUG & DEBUG_FALLBACKS) { fprintf(stderr, "Radeon begin rasterization fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } } else { rmesa->Fallback &= ~bit; if (oldfallback == bit) { _swrast_flush( ctx ); tnl->Driver.Render.Start = radeonRenderStart; tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive; tnl->Driver.Render.Finish = radeonRenderFinish; tnl->Driver.Render.BuildVertices = _tnl_build_vertices; tnl->Driver.Render.CopyPV = _tnl_copy_pv; tnl->Driver.Render.Interp = _tnl_interp; tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple; TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_FALSE ); if (rmesa->TclFallback) { /* These are already done if rmesa->TclFallback goes to * zero above. But not if it doesn't (RADEON_NO_TCL for * example?) */ _tnl_invalidate_vertex_state( ctx, ~0 ); _tnl_invalidate_vertices( ctx, ~0 ); RENDERINPUTS_ZERO( rmesa->tnl_index_bitset ); radeonChooseVertexState( ctx ); radeonChooseRenderState( ctx ); } if (RADEON_DEBUG & DEBUG_FALLBACKS) { fprintf(stderr, "Radeon end rasterization fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } }}/**********************************************************************//* Initialization. *//**********************************************************************/void radeonInitSwtcl( GLcontext *ctx ){ TNLcontext *tnl = TNL_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); static int firsttime = 1; if (firsttime) { init_rast_tab(); firsttime = 0; } tnl->Driver.Render.Start = radeonRenderStart; tnl->Driver.Render.Finish = radeonRenderFinish; tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive; tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple; tnl->Driver.Render.BuildVertices = _tnl_build_vertices; tnl->Driver.Render.CopyPV = _tnl_copy_pv; tnl->Driver.Render.Interp = _tnl_interp; _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, RADEON_MAX_TNL_VERTEX_SIZE); rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf; rmesa->swtcl.RenderIndex = ~0; rmesa->swtcl.render_primitive = GL_TRIANGLES; rmesa->swtcl.hw_primitive = 0;}void radeonDestroySwtcl( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if (rmesa->swtcl.indexed_verts.buf) radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -