📄 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 "texobj.h"#include "state.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_buffers.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 voidintel_flush_inline_primitive(struct intel_context *intel){ GLuint used = intel->batch->ptr - intel->prim.start_ptr; assert(intel->prim.primitive != ~0);/* _mesa_printf("/\n"); */ 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. */voidintelStartInlinePrimitive(struct intel_context *intel, GLuint prim, GLuint batch_flags){ BATCH_LOCALS; intel_wait_flips(intel); intel->vtbl.emit_state(intel); intel->no_batch_wrap = GL_TRUE;/* _mesa_printf("%s *", __progname); */ /* Emit a slot which will be filled with the inline primitive * command later. */ BEGIN_BATCH(2, batch_flags); OUT_BATCH(0); assert((intel->batch->dirty_state & (1<<1)) == 0); intel->prim.start_ptr = intel->batch->ptr; intel->prim.primitive = prim; intel->prim.flush = intel_flush_inline_primitive; OUT_BATCH(0); ADVANCE_BATCH(); intel->no_batch_wrap = GL_FALSE;/* _mesa_printf(">"); */}voidintelWrapInlinePrimitive(struct intel_context *intel){ GLuint prim = intel->prim.primitive; enum cliprect_mode cliprect_mode = intel->batch->cliprect_mode; intel_flush_inline_primitive(intel); intel_batchbuffer_flush(intel->batch); intelStartInlinePrimitive(intel, prim, cliprect_mode); /* ??? */}GLuint *intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords){ GLuint sz = dwords * sizeof(GLuint); GLuint *ptr; assert(intel->prim.flush == intel_flush_inline_primitive); if (intel_batchbuffer_space(intel->batch) < sz) intelWrapInlinePrimitive(intel);/* _mesa_printf("."); */ intel->vtbl.assert_not_dirty(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 voidintel_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); /* If smooth shading, draw like a trifan which gives better * rasterization. Otherwise draw as two triangles with provoking * vertex in third position as required for flat shading. */ if (intel->ctx.Light.ShadeModel == GL_FLAT) { COPY_DWORDS(j, vb, vertsize, v3); COPY_DWORDS(j, vb, vertsize, v1); } else { COPY_DWORDS(j, vb, vertsize, v2); COPY_DWORDS(j, vb, vertsize, v0); } COPY_DWORDS(j, vb, vertsize, v2); COPY_DWORDS(j, vb, vertsize, v3);}static voidintel_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 voidintel_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 voidintel_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; *(float *) &vb[1] = v0->v.y; for (j = 2; j < vertsize; j++) vb[j] = v0->ui[j];}/*********************************************************************** * Fixup for ARB_point_parameters * ***********************************************************************//* Currently not working - VERT_ATTRIB_POINTSIZE isn't correctly * represented in the fragment program InputsRead field. */static voidintel_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 voidintel_wpos_triangle(struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2){ GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); GLfloat *v1_wpos = (GLfloat *)((char *)v1 + offset); GLfloat *v2_wpos = (GLfloat *)((char *)v2 + offset); __memcpy(v0_wpos, v0, size); __memcpy(v1_wpos, v1, size); __memcpy(v2_wpos, v2, size); v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h; v1_wpos[1] = -v1_wpos[1] + intel->driDrawable->h; v2_wpos[1] = -v2_wpos[1] + intel->driDrawable->h; intel_draw_triangle(intel, v0, v1, v2);}static voidintel_wpos_line(struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1){ GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); GLfloat *v1_wpos = (GLfloat *)((char *)v1 + offset); __memcpy(v0_wpos, v0, size); __memcpy(v1_wpos, v1, size); v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h; v1_wpos[1] = -v1_wpos[1] + intel->driDrawable->h; intel_draw_line(intel, v0, v1);}static voidintel_wpos_point(struct intel_context *intel, intelVertexPtr v0){ GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); __memcpy(v0_wpos, v0, size); v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h; 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 ); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -