diff options
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.c | 37 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_fragprog.c | 39 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_render.c | 165 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_state.c | 48 |
5 files changed, 116 insertions, 174 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index d10a9d87d3..68c8f5b87d 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -133,7 +133,6 @@ const struct dri_extension stencil_two_side[] = { extern struct tnl_pipeline_stage _r300_render_stage; extern const struct tnl_pipeline_stage _r300_tcl_stage; -extern const struct tnl_pipeline_stage _r300_texrect_stage; static const struct tnl_pipeline_stage *r300_pipeline[] = { @@ -164,8 +163,6 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = { /* Else do them here. */ - /* scale texture rectangle to 0..1. */ - &_r300_texrect_stage, &_r300_render_stage, &_tnl_render_stage, /* FALLBACK */ 0, @@ -204,7 +201,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, "def_max_anisotropy"); //r300->texmicrotile = GL_TRUE; - + /* Init default driver functions then plug in our R300-specific functions * (the texture functions are especially important) */ @@ -213,7 +210,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, r300InitStateFuncs(&functions); r300InitTextureFuncs(&functions); r300InitShaderFuncs(&functions); - + #ifdef USER_BUFFERS radeon_mm_init(r300); #endif @@ -221,7 +218,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, if (hw_tcl_on) { r300_init_vbo_funcs(&functions); } -#endif +#endif if (!radeonInitContext(&r300->radeon, &functions, glVisual, driContextPriv, sharedContextPrivate)) { FREE(r300); @@ -264,8 +261,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, * texturable memory at once. */ - ctx = r300->radeon.glCtx; - + ctx = r300->radeon.glCtx; + ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache, "texture_image_units"); ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache, @@ -283,7 +280,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, ctx->Const.MinLineWidthAA = 1.0; ctx->Const.MaxLineWidth = R300_LINESIZE_MAX; ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX; - + #ifdef USER_BUFFERS /* Needs further modifications */ #if 0 @@ -337,10 +334,10 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, ctx->_MaintainTexEnvProgram = GL_TRUE; driInitExtensions(ctx, card_extensions, GL_TRUE); - + if (driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side") == 0) driInitSingleExtension(ctx, stencil_two_side); - + if (r300->radeon.glCtx->Mesa_DXTn && !driQueryOptionb (&r300->radeon.optionCache, "disable_s3tc")) { _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); _mesa_enable_extension( ctx, "GL_S3_s3tc" ); @@ -354,7 +351,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, radeonInitSpanFuncs(ctx); r300InitCmdBuf(r300); r300InitState(r300); - + #ifdef RADEON_VTXFMT_A radeon_init_vtxfmt_a(r300); #endif @@ -407,9 +404,9 @@ static void r300FreeGartAllocations(r300ContextPtr r300) /* Cannot flush/lock if no context exists. */ if (in_use) r300FlushCmdBuf(r300, __FUNCTION__); - + done_age = radeonGetAge((radeonContextPtr)r300); - + for (i = r300->rmm->u_last; i > 0; i--) { if (r300->rmm->u_list[i].ptr == NULL) { continue; @@ -421,7 +418,7 @@ static void r300FreeGartAllocations(r300ContextPtr r300) } assert(r300->rmm->u_list[i].h_pending == 0); - + tries = 0; while(r300->rmm->u_list[i].age > done_age && tries++ < 1000) { usleep(10); @@ -430,10 +427,10 @@ static void r300FreeGartAllocations(r300ContextPtr r300) if (tries >= 1000) { WARN_ONCE("Failed to idle region!"); } - + memfree.region_offset = (char *)r300->rmm->u_list[i].ptr - (char *)r300->radeon.radeonScreen->gartTextures.map; - + ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd, DRM_RADEON_FREE, &memfree, sizeof(memfree)); if (ret) { @@ -442,7 +439,7 @@ static void r300FreeGartAllocations(r300ContextPtr r300) } else { if (i == r300->rmm->u_last) r300->rmm->u_last--; - + r300->rmm->u_list[i].pending = 0; r300->rmm->u_list[i].ptr = NULL; if (r300->rmm->u_list[i].fb) { @@ -490,12 +487,12 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) _tnl_DestroyContext(r300->radeon.glCtx); _vbo_DestroyContext(r300->radeon.glCtx); _swrast_DestroyContext(r300->radeon.glCtx); - + if (r300->dma.current.buf) { r300ReleaseDmaRegion(r300, &r300->dma.current, __FUNCTION__ ); #ifndef USER_BUFFERS r300FlushCmdBuf(r300, __FUNCTION__); -#endif +#endif } r300FreeGartAllocations(r300); r300DestroyCmdBuf(r300); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index fa0f55446b..c8b81d9849 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -553,6 +553,7 @@ struct r300_stencilbuffer_state { #define VSF_MAX_FRAGMENT_TEMPS (14) #define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0) +#define STATE_R300_TEXRECT_FACTOR (STATE_INTERNAL_DRIVER+1) struct r300_vertex_shader_fragment { int length; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 0d7d1f1af2..68a75ec7f0 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -929,13 +929,40 @@ static void emit_tex(struct r300_fragment_program *rp, COMPILE_STATE; GLuint coord = t_src(rp, fpi->SrcReg[0]); GLuint dest = undef, rdest = undef; - GLuint din = cs->dest_in_node, uin = cs->used_in_node; + GLuint din, uin; int unit = fpi->TexSrcUnit; int hwsrc, hwdest; + GLuint tempreg = 0; /* Resolve source/dest to hardware registers */ - hwsrc = t_hw_src(rp, coord, GL_TRUE); if (opcode != R300_FPITX_OP_KIL) { + if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) { + /** + * Hardware uses [0..1]x[0..1] range for rectangle textures + * instead of [0..Width]x[0..Height]. + * Add a scaling instruction. + * + * \todo Refactor this once we have proper rewriting/optimization + * support for programs. + */ + GLint tokens[6] = { STATE_INTERNAL, STATE_R300_TEXRECT_FACTOR, 0, 0, 0, 0 }; + int factor_index; + GLuint factorreg; + + tokens[2] = unit; + factor_index = _mesa_add_state_reference(rp->mesa_program.Base.Parameters, tokens); + factorreg = emit_const4fv(rp, + rp->mesa_program.Base.Parameters->ParameterValues[factor_index]); + tempreg = keep(get_temp_reg(rp)); + + emit_arith(rp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW, + coord, factorreg, pfs_zero, 0); + + hwsrc = t_hw_src(rp, tempreg, GL_TRUE); + } else { + hwsrc = t_hw_src(rp, coord, GL_TRUE); + } + dest = t_dst(rp, fpi->DstReg); /* r300 doesn't seem to be able to do TEX->output reg */ @@ -956,8 +983,12 @@ static void emit_tex(struct r300_fragment_program *rp, } else { hwdest = 0; unit = 0; + hwsrc = t_hw_src(rp, coord, GL_TRUE); } + din = cs->dest_in_node; + uin = cs->used_in_node; + /* Indirection if source has been written in this node, or if the * dest has been read/written in this node */ @@ -1009,6 +1040,10 @@ static void emit_tex(struct r300_fragment_program *rp, pfs_one, pfs_zero, 0); free_temp(rp, dest); } + + /* Free temp register */ + if (tempreg != 0) + free_temp(rp, tempreg); } diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 0864558e8d..63b21b9379 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -202,23 +202,23 @@ static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_ unsigned long t_addr; unsigned long magic_1, magic_2; GLcontext *ctx; - ctx = rmesa->radeon.glCtx; - + ctx = rmesa->radeon.glCtx; + assert(elt_size == 2 || elt_size == 4); - + if(addr & (elt_size-1)){ WARN_ONCE("Badly aligned buffer\n"); return ; } #ifdef OPTIMIZE_ELTS addr_a = 0; - + magic_1 = (addr % 32) / 4; t_addr = addr & (~0x1d); magic_2 = (vertex_count + 1 + (t_addr & 0x2)) / 2 + magic_1; - + check_space(6); - + start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0); if(elt_size == 4){ e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); @@ -234,7 +234,7 @@ static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_ e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2); e32(t_addr); } - + if(elt_size == 4){ e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */ } else { @@ -249,11 +249,11 @@ static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_ #endif #else (void)magic_2, (void)magic_1, (void)t_addr; - + addr_a = 0; - + check_space(6); - + start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0); if(elt_size == 4){ e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); @@ -264,14 +264,14 @@ static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_ start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2); e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); e32(addr /*& 0xffffffe3*/); - + if(elt_size == 4){ e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */ } else { e32((vertex_count+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */ } //cp_delay(rmesa, 1); -#endif +#endif } static void r300_render_vb_primitive(r300ContextPtr rmesa, @@ -303,12 +303,12 @@ static void r300_render_vb_primitive(r300ContextPtr rmesa, //e32(rmesa->state.Elts[start]); return; } - + if(num_verts > 65535){ /* not implemented yet */ WARN_ONCE("Too many elts\n"); return; } - + r300EmitElts(ctx, rmesa->state.VB.Elts, num_verts, rmesa->state.VB.elt_size); fire_EB(rmesa, rmesa->state.elt_dma.aos_offset, num_verts, type, rmesa->state.VB.elt_size); #endif @@ -328,7 +328,7 @@ GLboolean r300_run_vb_render(GLcontext *ctx, int cmd_written = 0; drm_radeon_cmd_header_t *cmd = NULL; - + if (RADEON_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__); @@ -336,26 +336,26 @@ GLboolean r300_run_vb_render(GLcontext *ctx, TNLcontext *tnl = TNL_CONTEXT(ctx); radeon_vb_to_rvb(rmesa, VB, &tnl->vb); } - + r300UpdateShaders(rmesa); if (r300EmitArrays(ctx)) return GL_TRUE; r300UpdateShaderStates(rmesa); - + reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0); e32(R300_RB3D_DSTCACHE_UNKNOWN_0A); reg_start(R300_RB3D_ZCACHE_CTLSTAT,0); e32(R300_RB3D_ZCACHE_UNKNOWN_03); - + r300EmitState(rmesa); - + for(i=0; i < VB->PrimitiveCount; i++){ GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; - + r300_render_vb_primitive(rmesa, ctx, start, start + length, prim); } @@ -453,11 +453,6 @@ int r300Fallback(GLcontext *ctx) /* GL_POINT_SPRITE_NV */ FALLBACK_IF(ctx->Point.PointSprite); - /* Fallback for rectangular texture */ - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) - if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT) - return R300_FALLBACK_TCL; - return R300_FALLBACK_NONE; } @@ -494,19 +489,19 @@ static GLboolean r300_run_tcl_render(GLcontext *ctx, { r300ContextPtr rmesa = R300_CONTEXT(ctx); struct r300_vertex_program *vp; - + hw_tcl_on=future_hw_tcl_on; - + if (RADEON_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__); if(hw_tcl_on == GL_FALSE) return GL_TRUE; - + if (r300Fallback(ctx) >= R300_FALLBACK_TCL) { hw_tcl_on = GL_FALSE; return GL_TRUE; } - + r300UpdateShaders(rmesa); vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); @@ -520,13 +515,13 @@ static GLboolean r300_run_tcl_render(GLcontext *ctx, TNLcontext *tnl = TNL_CONTEXT(ctx); struct tnl_cache *cache; struct tnl_cache_item *c; - + cache = tnl->vp_cache; c = cache->items[0xc000cc0e % cache->size]; - + if(c && c->data == vp) vp->native = GL_FALSE; - + #endif #if 0 vp->native = GL_FALSE; @@ -536,7 +531,7 @@ static GLboolean r300_run_tcl_render(GLcontext *ctx, return GL_TRUE; } //r300UpdateShaderStates(rmesa); - + return r300_run_vb_render(ctx, stage); } @@ -549,107 +544,3 @@ const struct tnl_pipeline_stage _r300_tcl_stage = { r300_run_tcl_render /* run */ }; -/* R300 texture rectangle expects coords in 0..1 range, not 0..dimension - * as in the extension spec. Need to translate here. - * - * Note that swrast expects 0..dimension, so if a fallback is active, - * don't do anything. (Maybe need to configure swrast to match hw) - */ -struct texrect_stage_data { - GLvector4f texcoord[MAX_TEXTURE_UNITS]; -}; - -#define TEXRECT_STAGE_DATA(stage) ((struct texrect_stage_data *)stage->privatePtr) - - -static GLboolean run_texrect_stage( GLcontext *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage); - r300ContextPtr rmesa = R300_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint i; - - if (rmesa->radeon.Fallback) - return GL_TRUE; - - for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { - if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT) { - struct gl_texture_object *texObj = ctx->Texture.Unit[i].CurrentRect; - struct gl_texture_image *texImage = texObj->Image[0][texObj->BaseLevel]; - const GLfloat iw = 1.0/texImage->Width; - const GLfloat ih = 1.0/texImage->Height; - GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data; - GLint instride = VB->TexCoordPtr[i]->stride; - GLfloat (*out)[4] = store->texcoord[i].data; - GLint j; - - store->texcoord[i].size = VB->TexCoordPtr[i]->size; - for (j = 0 ; j < VB->Count ; j++) { - switch (VB->TexCoordPtr[i]->size) { - case 4: - out[j][3] = in[3]; - /* fallthrough */ - case 3: - out[j][2] = in[2]; - /* fallthrough */ - default: - out[j][0] = in[0] * iw; - out[j][1] = in[1] * ih; - } - in = (GLfloat *)((GLubyte *)in + instride); - } - - VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i]; - } - } - - return GL_TRUE; -} - - -/* Called the first time stage->run() is invoked. - */ -static GLboolean alloc_texrect_data( GLcontext *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct texrect_stage_data *store; - GLuint i; - - stage->privatePtr = CALLOC(sizeof(*store)); - store = TEXRECT_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) - _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 ); - - return GL_TRUE; -} - -static void free_texrect_data( struct tnl_pipeline_stage *stage ) -{ - struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage); - GLuint i; - - if (store) { - for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) - if (store->texcoord[i].data) - _mesa_vector4f_free( &store->texcoord[i] ); - FREE( store ); - stage->privatePtr = NULL; - } -} - -const struct tnl_pipeline_stage _r300_texrect_stage = -{ - "r300 texrect stage", /* name */ - NULL, - alloc_texrect_data, - free_texrect_data, - NULL, - run_texrect_stage -}; - diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 4fd80e60fe..17658efdb2 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1058,23 +1058,41 @@ r300UpdateDrawBuffer(GLcontext *ctx) static void r300FetchStateParameter(GLcontext *ctx, const enum state_index state[], GLfloat *value) { - r300ContextPtr r300 = R300_CONTEXT(ctx); + r300ContextPtr r300 = R300_CONTEXT(ctx); - switch(state[0]) - { - case STATE_INTERNAL: - switch(state[1]) - { - case STATE_R300_WINDOW_DIMENSION: - value[0] = r300->radeon.dri.drawable->w*0.5f;/* width*0.5 */ - value[1] = r300->radeon.dri.drawable->h*0.5f;/* height*0.5 */ - value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */ - value[3] = 1.0F; /* not used */ - break; - default:; + switch(state[0]) { + case STATE_INTERNAL: + switch(state[1]) { + case STATE_R300_WINDOW_DIMENSION: + value[0] = r300->radeon.dri.drawable->w*0.5f;/* width*0.5 */ + value[1] = r300->radeon.dri.drawable->h*0.5f;/* height*0.5 */ + value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */ + value[3] = 1.0F; /* not used */ + break; + + case STATE_R300_TEXRECT_FACTOR: { + struct gl_texture_object* t = ctx->Texture.Unit[state[2]].CurrentRect; + + if (t && t->Image[0][t->BaseLevel]) { + struct gl_texture_image* image = t->Image[0][t->BaseLevel]; + value[0] = 1.0 / image->Width2; + value[1] = 1.0 / image->Height2; + } else { + value[0] = 1.0; + value[1] = 1.0; + } + value[2] = 1.0; + value[3] = 1.0; + break; } + + default: + break; + } + break; + + default: + break; } - default:; - } } /** |