📄 i830_metaops.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 "enums.h"#include "mtypes.h"#include "macros.h"#include "utils.h"#include "intel_screen.h"#include "intel_batchbuffer.h"#include "intel_ioctl.h"#include "i830_context.h"#include "i830_reg.h"/* A large amount of state doesn't need to be uploaded. */#define ACTIVE (I830_UPLOAD_TEXBLEND(0) | \ I830_UPLOAD_STIPPLE | \ I830_UPLOAD_CTX | \ I830_UPLOAD_BUFFERS | \ I830_UPLOAD_TEX(0)) #define SET_STATE( i830, STATE ) \do { \ assert(!i830->intel.prim.flush); \ i830->current->emitted = 0; \ i830->current = &i830->STATE; \ i830->current->emitted = 0; \} while (0)/* Operations where the 3D engine is decoupled temporarily from the * current GL state and used for other purposes than simply rendering * incoming triangles. */static void set_initial_state( i830ContextPtr i830 ){ memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) ); i830->meta.active = ACTIVE; i830->meta.emitted = 0;}static void set_no_depth_stencil_write( i830ContextPtr i830 ){ /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) */ i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) */ i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; i830->meta.emitted &= ~I830_UPLOAD_CTX;}/* Set stencil unit to replace always with the reference value. */static void set_stencil_replace( i830ContextPtr i830, GLuint s_mask, GLuint s_clear){ /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) */ i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) */ i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; /* ctx->Driver.StencilMask( ctx, s_mask ) */ i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK((s_mask&0xff))); /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) */ i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); i830->meta.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | STENCIL_FAIL_OP(STENCILOP_REPLACE) | STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) */ i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff)); i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | ENABLE_STENCIL_TEST_FUNC_MASK); i830->meta.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | ENABLE_STENCIL_TEST_FUNC | STENCIL_REF_VALUE((s_clear&0xff)) | STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); i830->meta.emitted &= ~I830_UPLOAD_CTX;}static void set_color_mask( i830ContextPtr i830, GLboolean state ){ const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | (1 << WRITEMASK_GREEN_SHIFT) | (1 << WRITEMASK_BLUE_SHIFT) | (1 << WRITEMASK_ALPHA_SHIFT)); i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; if (state) { i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); } i830->meta.emitted &= ~I830_UPLOAD_CTX;}/* Installs a one-stage passthrough texture blend pipeline. Is there * more that can be done to turn off texturing? */static void set_no_texture( i830ContextPtr i830 ){ static const struct gl_tex_env_combine_state comb = { GL_NONE, GL_NONE, { GL_TEXTURE, 0, 0, }, { GL_TEXTURE, 0, 0, }, { GL_SRC_COLOR, 0, 0 }, { GL_SRC_ALPHA, 0, 0 }, 0, 0, 0, 0 }; i830->meta.TexBlendWordsUsed[0] = i830SetTexEnvCombine( i830, & comb, 0, TEXBLENDARG_TEXEL0, i830->meta.TexBlend[0], NULL); i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0);}/* Set up a single element blend stage for 'replace' texturing with no * funny ops. */static void enable_texture_blend_replace( i830ContextPtr i830 ){ static const struct gl_tex_env_combine_state comb = { GL_REPLACE, GL_REPLACE, { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE }, { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE, }, { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR }, { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA }, 0, 0, 1, 1 }; i830->meta.TexBlendWordsUsed[0] = i830SetTexEnvCombine( i830, & comb, 0, TEXBLENDARG_TEXEL0, i830->meta.TexBlend[0], NULL); i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0);/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", *//* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */}/* Set up an arbitary piece of memory as a rectangular texture * (including the front or back buffer). */static void set_tex_rect_source( i830ContextPtr i830, GLuint offset, GLuint width, GLuint height, GLuint pitch, /* in bytes */ GLuint textureFormat ){ GLint numLevels = 1; GLuint *setup = i830->meta.Tex[0];/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", *//* __FUNCTION__, offset, width, height, pitch, textureFormat ); */ setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | (LOAD_TEXTURE_MAP0 << 0) | 4); setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | offset); setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | ((width - 1) << TM0S1_WIDTH_SHIFT) | textureFormat); setup[I830_TEXREG_TM0S2] = ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT)); setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | MAP_UNIT(0) | ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_IN_TEXELUNITS | TEXCOORDTYPE_CARTESIAN | ENABLE_ADDR_V_CNTL | TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); i830->meta.emitted &= ~I830_UPLOAD_TEX(0);}/* Select between front and back draw buffers. */static void set_draw_region( i830ContextPtr i830, const intelRegion *region ){ i830->meta.Buffer[I830_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE); i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = region->offset; i830->meta.emitted &= ~I830_UPLOAD_BUFFERS;}/* Setup an arbitary draw format, useful for targeting * texture or agp memory. */#if 0static void set_draw_format( i830ContextPtr i830, GLuint format, GLuint depth_format){ i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ DSTORG_VERT_BIAS(0x8) | /* .5 */ format | DEPTH_IS_Z | depth_format);}#endifstatic void set_vertex_format( i830ContextPtr i830 ){ i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | VFT0_TEX_COUNT(1) | VFT0_DIFFUSE | VFT0_SPEC | VFT0_XYZW); i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | VFT1_TEX0_FMT(TEXCOORDFMT_2D) | VFT1_TEX1_FMT(TEXCOORDFMT_2D) | VFT1_TEX2_FMT(TEXCOORDFMT_2D) | VFT1_TEX3_FMT(TEXCOORDFMT_2D)); i830->meta.emitted &= ~I830_UPLOAD_CTX;}static void draw_quad(i830ContextPtr i830, GLfloat x0, GLfloat x1, GLfloat y0, GLfloat y1, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha, GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1 ){ GLuint vertex_size = 8; GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel, PRIM3D_TRIFAN, 4*vertex_size, vertex_size ); intelVertex tmp; int i; /* fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", *//* __FUNCTION__, *//* x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); */ /* initial vertex, left bottom */ tmp.v.x = x0; tmp.v.y = y0; tmp.v.z = 1.0; tmp.v.w = 1.0; tmp.v.color.red = red; tmp.v.color.green = green; tmp.v.color.blue = blue; tmp.v.color.alpha = alpha; tmp.v.specular.red = 0; tmp.v.specular.green = 0; tmp.v.specular.blue = 0; tmp.v.specular.alpha = 0; tmp.v.u0 = s0; tmp.v.v0 = t0; for (i = 0 ; i < 8 ; i++) vb[i] = tmp.ui[i]; /* right bottom */ vb += 8; tmp.v.x = x1; tmp.v.u0 = s1; for (i = 0 ; i < 8 ; i++) vb[i] = tmp.ui[i]; /* right top */ vb += 8; tmp.v.y = y1; tmp.v.v0 = t1; for (i = 0 ; i < 8 ; i++) vb[i] = tmp.ui[i]; /* left top */ vb += 8; tmp.v.x = x0; tmp.v.u0 = s0; for (i = 0 ; i < 8 ; i++) vb[i] = tmp.ui[i];/* fprintf(stderr, "%s: DV1: %x\n", *//* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */}static void draw_poly(i830ContextPtr i830, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha, GLuint numVerts, GLfloat verts[][2], GLfloat texcoords[][2]){ GLuint vertex_size = 8; GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel, PRIM3D_TRIFAN, numVerts * vertex_size, vertex_size ); intelVertex tmp; int i, k; /* initial constant vertex fields */ tmp.v.z = 1.0; tmp.v.w = 1.0; tmp.v.color.red = red; tmp.v.color.green = green; tmp.v.color.blue = blue; tmp.v.color.alpha = alpha; tmp.v.specular.red = 0; tmp.v.specular.green = 0; tmp.v.specular.blue = 0; tmp.v.specular.alpha = 0; for (k = 0; k < numVerts; k++) { tmp.v.x = verts[k][0]; tmp.v.y = verts[k][1]; tmp.v.u0 = texcoords[k][0]; tmp.v.v0 = texcoords[k][1]; for (i = 0 ; i < vertex_size ; i++) vb[i] = tmp.ui[i]; vb += vertex_size; }}void i830ClearWithTris(intelContextPtr intel, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch){ i830ContextPtr i830 = I830_CONTEXT( intel ); __DRIdrawablePrivate *dPriv = intel->driDrawable; intelScreenPrivate *screen = intel->intelScreen; int x0, y0, x1, y1; INTEL_FIREVERTICES(intel); SET_STATE( i830, meta ); set_initial_state( i830 );/* set_no_texture( i830 ); */ set_vertex_format( i830 ); LOCK_HARDWARE(intel); if(!all) { x0 = cx; y0 = cy; x1 = x0 + cw; y1 = y0 + ch; } else { x0 = 0; y0 = 0; x1 = x0 + dPriv->w; y1 = y0 + dPriv->h; } /* Don't do any clipping to screen - these are window coordinates. * The active cliprects will be applied as for any other geometry. */ if(mask & BUFFER_BIT_FRONT_LEFT) { set_no_depth_stencil_write( i830 ); set_color_mask( i830, GL_TRUE ); set_draw_region( i830, &screen->front ); draw_quad(i830, x0, x1, y0, y1, intel->clear_red, intel->clear_green, intel->clear_blue, intel->clear_alpha, 0, 0, 0, 0); } if(mask & BUFFER_BIT_BACK_LEFT) { set_no_depth_stencil_write( i830 ); set_color_mask( i830, GL_TRUE ); set_draw_region( i830, &screen->back ); draw_quad(i830, x0, x1, y0, y1, intel->clear_red, intel->clear_green, intel->clear_blue, intel->clear_alpha, 0, 0, 0, 0); } if(mask & BUFFER_BIT_STENCIL) { set_stencil_replace( i830, intel->ctx.Stencil.WriteMask[0], intel->ctx.Stencil.Clear); set_color_mask( i830, GL_FALSE ); set_draw_region( i830, &screen->front ); draw_quad( i830, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -