struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx, const int *key ) { #if 0 static char temp[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ 0x83, 0xe0, 0x01, /* and $0x1,%eax */ 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ 0x89, 0x90, 0, 0, 0, 0, /* mov %edx,DEST(%eax) */ 0x89, 0x88, 0, 0, 0, 0, /* mov %ecx,DEST+8(%eax) */ 0xc3, /* ret */ }; static char temp2[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ 0x83, 0xe0, 0x01, /* and $0x1,%eax */ 0x8b, 0x04, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%eax */ 0x89, 0x10, /* mov %edx,(%eax) */ 0x89, 0x48, 0x04, /* mov %ecx,0x4(%eax) */ 0xc3, /* ret */ }; #endif struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); if (vb.texcoordptr[1] == vb.texcoordptr[0]+4) { DFN ( _x86_MultiTexCoord2fARB, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); FIXUP(dfn->code, 25, 0xdeadbeef, (int)vb.texcoordptr[0]); FIXUP(dfn->code, 31, 0xdeadbeef, (int)vb.texcoordptr[0]+4); } else { /* Note: this might get generated multiple times, even though the * actual emitted code is the same. */ DFN ( _x86_MultiTexCoord2fARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); FIXUP(dfn->code, 23, 0x0, (int)vb.texcoordptr); } return dfn; }
static void r200_Vertex2f( GLfloat x, GLfloat y ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); int i; *rmesa->vb.dmaptr++ = *(int *)&x; *rmesa->vb.dmaptr++ = *(int *)&y; *rmesa->vb.dmaptr++ = 0; for (i = 3; i < rmesa->vb.vertex_size; i++) *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; if (--rmesa->vb.counter == 0) rmesa->vb.notify(); }
static void r200_End( void ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s\n", __FUNCTION__); if (rmesa->vb.prim[0] == GL_POLYGON+1) { _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); return; } note_last_prim( rmesa, PRIM_END ); rmesa->vb.prim[0] = GL_POLYGON+1; }
static void r200_Vertex3fv( const GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); int i; *rmesa->vb.dmaptr++ = *(int *)&v[0]; *rmesa->vb.dmaptr++ = *(int *)&v[1]; *rmesa->vb.dmaptr++ = *(int *)&v[2]; for (i = 3; i < rmesa->vb.vertex_size; i++) *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; if (--rmesa->vb.counter == 0) rmesa->vb.notify(); }
/* Materials: */ static void r200_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT( ctx ); if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s\n", __FUNCTION__); if (rmesa->vb.prim[0] != GL_POLYGON+1) { VFMT_FALLBACK( __FUNCTION__ ); CALL_Materialfv(GET_DISPATCH(), (face, pname, params)); return; } _mesa_noop_Materialfv( face, pname, params ); r200UpdateMaterial( ctx ); }
struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) { if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) return 0; else { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); DFN ( _x86_Color3f_3f, rmesa->vb.dfn_cache.Color3f ); FIXUP(dfn->code, 1, 0x12345678, (int)vb.floatcolorptr); return dfn; } }
struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); int i = 0; if (R200_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); DFN ( _x86_Normal3fv, rmesa->vb.dfn_cache.Normal3fv ); FIXUP2(dfn->code, i, 0x0, (int)vb.normalptr); FIXUP2(dfn->code, i, 0x4, 4+(int)vb.normalptr); FIXUP2(dfn->code, i, 0x8, 8+(int)vb.normalptr); fprintf(stderr, "%s done\n", __FUNCTION__); return dfn; }
struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) { #if 0 static char temp[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ 0x83, 0xe0, 0x01, /* and $0x1,%eax */ 0x8b, 0x11, /* mov (%ecx),%edx */ 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ 0x8b, 0x49, 0x04, /* mov 0x4(%ecx),%ecx */ 0x89, 0x90, 0, 0, 0, 0,/* mov %edx,DEST(%eax) */ 0x89, 0x88, 0, 0, 0, 0,/* mov %ecx,DEST+8(%eax) */ 0xc3, /* ret */ }; static char temp2[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ 0x83, 0xe0, 0x01, /* and $0x1,%eax */ 0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%edx */ 0x8b, 0x01, /* mov (%ecx),%eax */ 0x89, 0x02, /* mov %eax,(%edx) */ 0x8b, 0x41, 0x04, /* mov 0x4(%ecx),%eax */ 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ 0xc3, /* ret */ }; #endif struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); if (vb.texcoordptr[1] == vb.texcoordptr[0]+4) { DFN ( _x86_MultiTexCoord2fvARB, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); FIXUP(dfn->code, 26, 0xdeadbeef, (int)vb.texcoordptr[0]); FIXUP(dfn->code, 32, 0xdeadbeef, (int)vb.texcoordptr[0]+4); } else { DFN ( _x86_MultiTexCoord2fvARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); FIXUP(dfn->code, 19, 0x0, (int)vb.texcoordptr); } return dfn; }
/* Called via glXGetMemoryOffsetMESA() */ GLuint r200GetMemoryOffsetMESA(__DRIscreen *screen, const GLvoid *pointer) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa; GLuint card_offset; if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) { fprintf(stderr, "%s: no context\n", __FUNCTION__); return ~0; } if (!r200IsGartMemory( rmesa, pointer, 0 )) return ~0; card_offset = r200GartOffsetFromVirtual( rmesa, pointer ); return card_offset - rmesa->radeon.radeonScreen->gart_base; }
static void disable_tex( GLcontext *ctx, int unit ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit)) { /* Texture unit disabled */ rmesa->state.texture.unit[unit].texobj = 0; R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((R200_TEX_0_ENABLE | R200_TEX_BLEND_0_ENABLE) << unit); rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_BLEND_0_ENABLE; R200_STATECHANGE( rmesa, tcl ); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); if (rmesa->TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) { TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE); } /* Actually want to keep all units less than max active texture * enabled, right? Fix this for >2 texunits. */ if (unit == 0) r200UpdateTextureEnv( ctx, unit ); { GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4; GLuint tmp = rmesa->TexGenEnabled; rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); rmesa->TexGenEnabled &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); rmesa->TexGenNeedNormals[unit] = 0; rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); if (tmp != rmesa->TexGenEnabled) { rmesa->recheck_texgen[unit] = GL_TRUE; rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; } } } }
static void emit_ubyte_rgba( GLcontext *ctx, struct r200_dma_region *rvb, char *data, int size, int stride, int count ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); assert (!rvb->buf); if (stride == 0) { r200AllocDmaRegion( rmesa, rvb, 4, 4 ); count = 1; rvb->aos_start = GET_START(rvb); rvb->aos_stride = 0; rvb->aos_size = 1; } else { r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */ rvb->aos_start = GET_START(rvb); rvb->aos_stride = 1; rvb->aos_size = 1; } /* Emit the data */ switch (size) { case 3: emit_ubyte_rgba3( ctx, rvb, data, stride, count ); break; case 4: emit_ubyte_rgba4( ctx, rvb, data, stride, count ); break; default: assert(0); exit(1); break; } }
static void transition_to_hwtnl( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); _tnl_need_projected_coords( ctx, GL_FALSE ); r200UpdateMaterial( ctx ); tnl->Driver.NotifyMaterialChange = r200UpdateMaterial; if ( rmesa->dma.flush ) rmesa->dma.flush( rmesa ); rmesa->dma.flush = NULL; if (rmesa->swtcl.indexed_verts.buf) r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ ); R200_STATECHANGE( rmesa, vap ); rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE; rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE; if (ctx->VertexProgram._Enabled) { rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE; } if ( ((rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK) == R200_FOG_USE_SPEC_ALPHA) && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD )) { R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK; rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_VTX_FOG; } R200_STATECHANGE( rmesa, vte ); rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT); rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT; if (R200_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "R200 end tcl fallback\n"); }
struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key ) { if (R200_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); FIXUP(dfn->code, 18, 0x0, (int)vb.colorptr); FIXUP(dfn->code, 24, 0x0, (int)vb.colorptr+1); FIXUP(dfn->code, 30, 0x0, (int)vb.colorptr+2); FIXUP(dfn->code, 36, 0x0, (int)vb.colorptr+3); return dfn; } else return 0; }
/* This version of AllocateMemoryMESA allocates only GART memory, and * only does so after the point at which the driver has been * initialized. * * Theoretically a valid context isn't required. However, in this * implementation, it is, as I'm using the hardware lock to protect * the kernel data structures, and the current context to get the * device fd. */ void *r200AllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa; int region_offset; drm_radeon_mem_alloc_t alloc; int ret; if (R200_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq, writefreq, priority); if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->r200Screen->gartTextures.map) return NULL; if (getenv("R200_NO_ALLOC")) return NULL; if (rmesa->dri.drmMinor < 6) return NULL; alloc.region = RADEON_MEM_REGION_GART; alloc.alignment = 0; alloc.size = size; alloc.region_offset = ®ion_offset; ret = drmCommandWriteRead( rmesa->r200Screen->driScreen->fd, DRM_RADEON_ALLOC, &alloc, sizeof(alloc)); if (ret) { fprintf(stderr, "%s: DRM_RADEON_ALLOC ret %d\n", __FUNCTION__, ret); return NULL; } { char *region_start = (char *)rmesa->r200Screen->gartTextures.map; return (void *)(region_start + region_offset); } }
static void r200_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); GLint unit = (target & 7); GLfloat * const dest = rmesa->vb.texcoordptr[unit]; switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { case TEXTURE_CUBE_BIT: case TEXTURE_3D_BIT: dest[2] = r; dest[1] = t; dest[0] = s; break; default: VFMT_FALLBACK(__FUNCTION__); CALL_MultiTexCoord3fARB(GET_DISPATCH(), (target, s, t, r)); return; } }
/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */ static void r200_MultiTexCoord1fARB(GLenum target, GLfloat s) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); GLint unit = (target & 7); GLfloat * const dest = rmesa->vb.texcoordptr[unit]; switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { case TEXTURE_CUBE_BIT: case TEXTURE_3D_BIT: dest[2] = 0.0; /* FALLTHROUGH */ case TEXTURE_2D_BIT: case TEXTURE_RECT_BIT: dest[1] = 0.0; /* FALLTHROUGH */ case TEXTURE_1D_BIT: dest[0] = s; } }
static void emit_vecfog( GLcontext *ctx, struct r200_dma_region *rvb, char *data, int stride, int count ) { int i; GLfloat *out; r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s count %d stride %d\n", __FUNCTION__, count, stride); assert (!rvb->buf); if (stride == 0) { r200AllocDmaRegion( rmesa, rvb, 4, 4 ); count = 1; rvb->aos_start = GET_START(rvb); rvb->aos_stride = 0; rvb->aos_size = 1; } else { r200AllocDmaRegion( rmesa, rvb, count * 4, 4 ); /* alignment? */ rvb->aos_start = GET_START(rvb); rvb->aos_stride = 1; rvb->aos_size = 1; } /* Emit the data */ out = (GLfloat *)(rvb->address + rvb->start); for (i = 0; i < count; i++) { out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data ); out++; data += stride; } }
static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); if (ctx->Driver.NeedFlush) r200VtxFmtFlushVertices( ctx, ctx->Driver.NeedFlush ); if (ctx->NewState) _mesa_update_state( ctx ); /* clear state so fell_back sticks */ _tnl_wakeup_exec( ctx ); ctx->Driver.FlushVertices = r200FlushVertices; assert( rmesa->dma.flush == 0 ); rmesa->vb.fell_back = GL_TRUE; rmesa->vb.installed = GL_FALSE; }
static void r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog) { struct r200_vertex_program *vp = (void *)prog; r200ContextPtr rmesa = R200_CONTEXT(ctx); switch(target) { case GL_VERTEX_PROGRAM_ARB: vp->translated = GL_FALSE; vp->fogpidx = 0; /* memset(&vp->translated, 0, sizeof(struct r200_vertex_program) - sizeof(struct gl_vertex_program));*/ r200_translate_vertex_program(ctx, vp); rmesa->curr_vp_hw = NULL; break; case GL_FRAGMENT_SHADER_ATI: rmesa->afs_loaded = NULL; break; } /* need this for tcl fallbacks */ _tnl_program_string(ctx, target, prog); }
/* Called via glXGetMemoryOffsetMESA() */ GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa; GLuint card_offset; if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) { fprintf(stderr, "%s: no context\n", __FUNCTION__); return ~0; } if (!r200IsGartMemory( rmesa, pointer, 0 )) return ~0; if (rmesa->dri.drmMinor < 6) return ~0; card_offset = r200GartOffsetFromVirtual( rmesa, pointer ); return card_offset - rmesa->r200Screen->gart_base; }
/* TODO: Try to extend existing primitive if both are identical, * discrete and there are no intervening state changes. (Somewhat * duplicates changes to DrawArrays code) */ static void r200EmitPrim( struct gl_context *ctx, GLenum prim, GLuint hwprim, GLuint start, GLuint count) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); r200TclPrimitive( ctx, prim, hwprim ); // fprintf(stderr,"Emit prim %d\n", rmesa->radeon.tcl.aos_count); r200EmitAOS( rmesa, rmesa->radeon.tcl.aos_count, start ); /* Why couldn't this packet have taken an offset param? */ r200EmitVbufPrim( rmesa, rmesa->tcl.hw_primitive, count - start ); }
static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *tObj = texUnit->_Current; r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) { t->pp_txformat |= R200_TXFORMAT_NON_POWER2; t->dirty_images = ~0; } if ( t->dirty_images ) { R200_FIREVERTICES( rmesa ); r200SetTexImages( rmesa, tObj, GL_TEXTURE_RECTANGLE_NV ); if ( !t->memBlock && !rmesa->prefer_agp_client_texturing ) return GL_FALSE; } return GL_TRUE; }
static GLboolean clip_pixelrect( const GLcontext *ctx, const GLframebuffer *buffer, GLint *x, GLint *y, GLsizei *width, GLsizei *height, GLint *size ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); /* left clipping */ if (*x < buffer->_Xmin) { *width -= (buffer->_Xmin - *x); *x = buffer->_Xmin; } /* right clipping */ if (*x + *width > buffer->_Xmax) *width -= (*x + *width - buffer->_Xmax - 1); if (*width <= 0) return GL_FALSE; /* bottom clipping */ if (*y < buffer->_Ymin) { *height -= (buffer->_Ymin - *y); *y = buffer->_Ymin; } /* top clipping */ if (*y + *height > buffer->_Ymax) *height -= (*y + *height - buffer->_Ymax - 1); if (*height <= 0) return GL_FALSE; *size = ((*y + *height - 1) * rmesa->r200Screen->frontPitch + (*x + *width - 1) * rmesa->r200Screen->cpp); return GL_TRUE; }
static void transition_to_hwtnl( struct gl_context *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); _tnl_need_projected_coords( ctx, GL_FALSE ); r200UpdateMaterial( ctx ); tnl->Driver.NotifyMaterialChange = r200UpdateMaterial; if ( rmesa->radeon.dma.flush ) rmesa->radeon.dma.flush( &rmesa->radeon.glCtx ); rmesa->radeon.dma.flush = NULL; R200_STATECHANGE( rmesa, vap ); rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE; rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE; if (_mesa_arb_vertex_program_enabled(ctx)) { rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE; } if ( ((rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK) == R200_FOG_USE_SPEC_ALPHA) && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD )) { R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK; rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_VTX_FOG; } R200_STATECHANGE( rmesa, vte ); rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT); rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT; if (R200_DEBUG & RADEON_FALLBACKS) fprintf(stderr, "R200 end tcl fallback\n"); }
void r200FlushElts(struct gl_context *ctx) { r200ContextPtr rmesa = R200_CONTEXT(ctx); int nr, elt_used = rmesa->tcl.elt_used; radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x %d\n", __FUNCTION__, rmesa->tcl.hw_primitive, elt_used); assert( rmesa->radeon.dma.flush == r200FlushElts ); rmesa->radeon.dma.flush = NULL; nr = elt_used / 2; radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo); r200FireEB(rmesa, nr, rmesa->tcl.hw_primitive); radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo); rmesa->radeon.tcl.elt_dma_bo = NULL; if (R200_ELT_BUF_SZ > elt_used) radeonReturnDmaRegion(&rmesa->radeon, R200_ELT_BUF_SZ - elt_used); }
/* Called via glXFreeMemoryMESA() */ void r200FreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa; ptrdiff_t region_offset; drm_radeon_mem_free_t memfree; int ret; if (R200_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s %p\n", __FUNCTION__, pointer); if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->r200Screen->gartTextures.map) { fprintf(stderr, "%s: no context\n", __FUNCTION__); return; } if (rmesa->dri.drmMinor < 6) return; region_offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map; if (region_offset < 0 || region_offset > rmesa->r200Screen->gartTextures.size) { fprintf(stderr, "offset %d outside range 0..%d\n", region_offset, rmesa->r200Screen->gartTextures.size); return; } memfree.region = RADEON_MEM_REGION_GART; memfree.region_offset = region_offset; ret = drmCommandWrite( rmesa->r200Screen->driScreen->fd, DRM_RADEON_FREE, &memfree, sizeof(memfree)); if (ret) fprintf(stderr, "%s: DRM_RADEON_FREE ret %d\n", __FUNCTION__, ret); }
static void transition_to_swtnl( struct gl_context *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); R200_NEWPRIM( rmesa ); r200ChooseVertexState( ctx ); r200ChooseRenderState( ctx ); _tnl_validate_shine_tables( ctx ); tnl->Driver.NotifyMaterialChange = _tnl_validate_shine_tables; radeonReleaseArrays( ctx, ~0 ); /* Still using the D3D based hardware-rasterizer from the radeon; * need to put the card into D3D mode to make it work: */ R200_STATECHANGE( rmesa, vap ); rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_TCL_ENABLE|R200_VAP_PROG_VTX_SHADER_ENABLE); }
static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *tObj = texUnit->_Current; r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; /* Need to load the 2d images associated with this unit. */ if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; t->dirty_images = ~0; } if ( t->dirty_images ) { R200_FIREVERTICES( rmesa ); r200SetTexImages( rmesa, tObj, GL_TEXTURE_2D ); if ( !t->memBlock ) return GL_FALSE; } return GL_TRUE; }
/* TODO: Try to extend existing primitive if both are identical, * discrete and there are no intervening state changes. (Somewhat * duplicates changes to DrawArrays code) */ static void r200EmitPrim( GLcontext *ctx, GLenum prim, GLuint hwprim, GLuint start, GLuint count) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); r200TclPrimitive( ctx, prim, hwprim ); r200EnsureCmdBufSpace( rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) + rmesa->hw.max_state_size + VBUF_BUFSZ ); r200EmitAOS( rmesa, rmesa->tcl.aos_components, rmesa->tcl.nr_aos_components, start ); /* Why couldn't this packet have taken an offset param? */ r200EmitVbufPrim( rmesa, rmesa->tcl.hw_primitive, count - start ); }
static void r200VtxfmtValidate( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s\n", __FUNCTION__); if (ctx->Driver.NeedFlush) ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); rmesa->vb.recheck = GL_FALSE; if (check_vtx_fmt( ctx )) { if (!rmesa->vb.installed) { if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "reinstall (new install)\n"); _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); ctx->Driver.FlushVertices = r200VtxFmtFlushVertices; rmesa->vb.installed = GL_TRUE; } else if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s: already installed", __FUNCTION__); } else { if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s: failed\n", __FUNCTION__); if (rmesa->vb.installed) { if (rmesa->dma.flush) rmesa->dma.flush( rmesa ); _tnl_wakeup_exec( ctx ); ctx->Driver.FlushVertices = r200FlushVertices; rmesa->vb.installed = GL_FALSE; } } }