📄 intel_tris.c
字号:
/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/#include "glheader.h"#include "context.h"#include "macros.h"#include "enums.h"#include "dd.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"#include "tnl/t_vertex.h"#include "intel_screen.h"#include "intel_context.h"#include "intel_tris.h"#include "intel_batchbuffer.h"#include "intel_reg.h"#include "intel_span.h"#include "intel_tex.h"static void intelRenderPrimitive( GLcontext *ctx, GLenum prim );static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );/* */static void intel_flush_inline_primitive( struct intel_context *intel ){ GLuint used = intel->batch->ptr - intel->prim.start_ptr; assert(intel->prim.primitive != ~0); if (used < 8) goto do_discard; *(int *)intel->prim.start_ptr = (_3DPRIMITIVE | intel->prim.primitive | (used/4-2)); goto finished; do_discard: intel->batch->ptr -= used; finished: intel->prim.primitive = ~0; intel->prim.start_ptr = 0; intel->prim.flush = 0;}/* Emit a primitive referencing vertices in a vertex buffer. */void intelStartInlinePrimitive( struct intel_context *intel, GLuint prim, GLuint batch_flags ){ BATCH_LOCALS; /* Emit a slot which will be filled with the inline primitive * command later. */ BEGIN_BATCH(2, batch_flags); OUT_BATCH( 0 ); intel->prim.start_ptr = intel->batch->ptr; intel->prim.primitive = prim; intel->prim.flush = intel_flush_inline_primitive; OUT_BATCH( 0 ); ADVANCE_BATCH();}void intelWrapInlinePrimitive( struct intel_context *intel ){ GLuint prim = intel->prim.primitive; GLuint batchflags = intel->batch->flags; intel_flush_inline_primitive(intel); intel_batchbuffer_flush(intel->batch); intel->vtbl.emit_state( intel ); intelStartInlinePrimitive( intel, prim, batchflags ); /* ??? */}GLuint *intelExtendInlinePrimitive( struct intel_context *intel, GLuint dwords ){ GLuint sz = dwords * sizeof(GLuint); GLuint *ptr; if (intel_batchbuffer_space(intel->batch) < sz) intelWrapInlinePrimitive( intel ); ptr = (GLuint *)intel->batch->ptr; intel->batch->ptr += sz; return ptr;}/*********************************************************************** * Emit primitives as inline vertices * ***********************************************************************/#ifdef __i386__#define COPY_DWORDS( j, vb, vertsize, v ) \do { \ int __tmp; \ __asm__ __volatile__( "rep ; movsl" \ : "=%c" (j), "=D" (vb), "=S" (__tmp) \ : "0" (vertsize), \ "D" ((long)vb), \ "S" ((long)v) ); \} while (0)#else#define COPY_DWORDS( j, vb, vertsize, v ) \do { \ for ( j = 0 ; j < vertsize ; j++ ) { \ vb[j] = ((GLuint *)v)[j]; \ } \ vb += vertsize; \} while (0)#endifstatic void intel_draw_quad( struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2, intelVertexPtr v3 ){ GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, 6 * vertsize ); int j; COPY_DWORDS( j, vb, vertsize, v0 ); COPY_DWORDS( j, vb, vertsize, v1 ); COPY_DWORDS( j, vb, vertsize, v3 ); COPY_DWORDS( j, vb, vertsize, v1 ); COPY_DWORDS( j, vb, vertsize, v2 ); COPY_DWORDS( j, vb, vertsize, v3 );}static void intel_draw_triangle( struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2 ){ GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, 3 * vertsize ); int j; COPY_DWORDS( j, vb, vertsize, v0 ); COPY_DWORDS( j, vb, vertsize, v1 ); COPY_DWORDS( j, vb, vertsize, v2 );}static void intel_draw_line( struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1 ){ GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, 2 * vertsize ); int j; COPY_DWORDS( j, vb, vertsize, v0 ); COPY_DWORDS( j, vb, vertsize, v1 );}static void intel_draw_point( struct intel_context *intel, intelVertexPtr v0 ){ GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, vertsize ); int j; /* Adjust for sub pixel position -- still required for conform. */ *(float *)&vb[0] = v0->v.x - 0.125; *(float *)&vb[1] = v0->v.y - 0.125; for (j = 2 ; j < vertsize ; j++) vb[j] = v0->ui[j];}/*********************************************************************** * Fixup for ARB_point_parameters * ***********************************************************************/static void intel_atten_point( struct intel_context *intel, intelVertexPtr v0 ){ GLcontext *ctx = &intel->ctx; GLfloat psz[4], col[4], restore_psz, restore_alpha; _tnl_get_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz ); _tnl_get_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col ); restore_psz = psz[0]; restore_alpha = col[3]; if (psz[0] >= ctx->Point.Threshold) { psz[0] = MIN2(psz[0], ctx->Point.MaxSize); } else { GLfloat dsize = psz[0] / ctx->Point.Threshold; psz[0] = MAX2(ctx->Point.Threshold, ctx->Point.MinSize); col[3] *= dsize * dsize; } if (psz[0] < 1.0) psz[0] = 1.0; if (restore_psz != psz[0] || restore_alpha != col[3]) { _tnl_set_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); _tnl_set_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col); intel_draw_point( intel, v0 ); psz[0] = restore_psz; col[3] = restore_alpha; _tnl_set_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); _tnl_set_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col); } else intel_draw_point( intel, v0 );}/*********************************************************************** * Fixup for I915 WPOS texture coordinate * ***********************************************************************/static void intel_wpos_triangle( struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2 ){ GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; __memcpy( ((char *)v0) + offset, v0, size ); __memcpy( ((char *)v1) + offset, v1, size ); __memcpy( ((char *)v2) + offset, v2, size ); intel_draw_triangle( intel, v0, v1, v2 );}static void intel_wpos_line( struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1 ){ GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; __memcpy( ((char *)v0) + offset, v0, size ); __memcpy( ((char *)v1) + offset, v1, size ); intel_draw_line( intel, v0, v1 );}static void intel_wpos_point( struct intel_context *intel, intelVertexPtr v0 ){ GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; __memcpy( ((char *)v0) + offset, v0, size ); intel_draw_point( intel, v0 );}/*********************************************************************** * Macros for t_dd_tritmp.h to draw basic primitives * ***********************************************************************/#define TRI( a, b, c ) \do { \ if (DO_FALLBACK) \ intel->draw_tri( intel, a, b, c ); \ else \ intel_draw_triangle( intel, a, b, c ); \} while (0)#define QUAD( a, b, c, d ) \do { \ if (DO_FALLBACK) { \ intel->draw_tri( intel, a, b, d ); \ intel->draw_tri( intel, b, c, d ); \ } else \ intel_draw_quad( intel, a, b, c, d ); \} while (0)#define LINE( v0, v1 ) \do { \ if (DO_FALLBACK) \ intel->draw_line( intel, v0, v1 ); \ else \ intel_draw_line( intel, v0, v1 ); \} while (0)#define POINT( v0 ) \do { \ if (DO_FALLBACK) \ intel->draw_point( intel, v0 ); \ else \ intel_draw_point( intel, v0 ); \} while (0)/*********************************************************************** * Build render functions from dd templates * ***********************************************************************/#define INTEL_OFFSET_BIT 0x01#define INTEL_TWOSIDE_BIT 0x02#define INTEL_UNFILLED_BIT 0x04#define INTEL_FALLBACK_BIT 0x08#define INTEL_MAX_TRIFUNC 0x10static struct { tnl_points_func points; tnl_line_func line; tnl_triangle_func triangle; tnl_quad_func quad;} rast_tab[INTEL_MAX_TRIFUNC];#define DO_FALLBACK (IND & INTEL_FALLBACK_BIT)#define DO_OFFSET (IND & INTEL_OFFSET_BIT)#define DO_UNFILLED (IND & INTEL_UNFILLED_BIT)#define DO_TWOSIDE (IND & INTEL_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 VERTEX intelVertex#define TAB rast_tab/* Only used to pull back colors into vertices (ie, we know color is * floating point). */#define INTEL_COLOR( dst, src ) \do { \ UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \} while (0)#define INTEL_SPEC( dst, src ) \do { \ UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \} while (0)#define DEPTH_SCALE intel->polygon_offset_scale#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) (intel->verts + (e * intel->vertex_size * sizeof(GLuint)))#define VERT_SET_RGBA( v, c ) if (coloroffset) INTEL_COLOR( v->ub4[coloroffset], c )#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset]#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset]#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx]#define VERT_SET_SPEC( v, c ) if (specoffset) INTEL_SPEC( v->ub4[specoffset], c )#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset])#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]#define LOCAL_VARS(n) \ struct intel_context *intel = intel_context(ctx); \ GLuint color[n], spec[n]; \ GLuint coloroffset = intel->coloroffset; \ GLboolean specoffset = intel->specoffset; \ (void) color; (void) spec; (void) coloroffset; (void) specoffset;/*********************************************************************** * Helpers for rendering unfilled primitives * ***********************************************************************/static const GLuint hw_prim[GL_POLYGON+1] = { PRIM3D_POINTLIST, PRIM3D_LINELIST, PRIM3D_LINELIST, PRIM3D_LINELIST, PRIM3D_TRILIST, PRIM3D_TRILIST, PRIM3D_TRILIST, PRIM3D_TRILIST, PRIM3D_TRILIST, PRIM3D_TRILIST};#define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] )#define RENDER_PRIMITIVE intel->render_primitive#define TAG(x) x#define IND INTEL_FALLBACK_BIT#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 (INTEL_OFFSET_BIT)#define TAG(x) x##_offset#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_TWOSIDE_BIT)#define TAG(x) x##_twoside#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT)#define TAG(x) x##_twoside_offset#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_UNFILLED_BIT)#define TAG(x) x##_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT)#define TAG(x) x##_offset_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT)#define TAG(x) x##_twoside_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT)#define TAG(x) x##_twoside_offset_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_FALLBACK_BIT)#define TAG(x) x##_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT)#define TAG(x) x##_offset_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT)#define TAG(x) x##_twoside_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT)#define TAG(x) x##_twoside_offset_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)#define TAG(x) x##_unfilled_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)#define TAG(x) x##_offset_unfilled_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)#define TAG(x) x##_twoside_unfilled_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \ INTEL_FALLBACK_BIT)#define TAG(x) x##_twoside_offset_unfilled_fallback#include "tnl_dd/t_dd_tritmp.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -