Brian Paul wrote:
Keith Whitwell wrote:
Andreas Stenglein wrote:
Am 2003.06.10 12:12:56 +0200 schrieb(en) Keith Whitwell:
Keith Whitwell wrote:yes, its unbelievable... it works with texcoords 0...1 ;)
Andreas Stenglein wrote:
@keithw: here is another version.
yuvrect.c seems to work texrect.c still doesnt work
any hints?
OK, the final piece of the puzzle fell into place. Without the radeon docs you might hav had trouble find this -- basically, the radeon still expects texture rectangle texcoords to be in 0..1 range, rather than 0..width,0..height like the r200.
I haven't got the code running for this yet, but modifying the app to supply the texcoords the hardware expects gives a good image.
Keith
1) Do you have an idea how to make it work with the right texcoords?
I was thinking that this would be a fairly easy option:
a) Disable TCL for all rectangular texture operations
b) Insert a new stage to the swtcl pipeline, based on Mesa/src/tnl/t_vb_texmat.c, to perform a 1/w, 1/h scale to all texrect coordinates.
c) premultiply the texture matrix by a scaling matrix?
I wanted to keep things seperate -- but it does sound nice. It would need some new infrastructure - if it were to work with tcl fallbacks, then t_vb_texmat.c would have to use a premultiplied one also. Further, swrast expects "normal" 0..dimension texcoords, so it would have to be turned off during rasterization fallbacks.
It seems like it would require hooks into core mesa, just to deal with this one piece of hardware that works this way. Adding a new renderstage keeps it in the driver.
I could add a new renderstage *and* premultiply only the hw texture matrix (keeping hwtcl), but that's even more work.
Here's a patch that mainly works. I've still seen the odd case of the texture apparently getting uploaded to the backbuffer.
Keith
? Am ? diff ? ff Index: radeon_context.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v retrieving revision 1.38 diff -u -r1.38 radeon_context.c --- radeon_context.c 26 May 2003 19:48:51 -0000 1.38 +++ radeon_context.c 10 Jun 2003 15:37:48 -0000 @@ -147,6 +147,7 @@ NULL }; +extern const struct gl_pipeline_stage _radeon_texrect_stage; extern const struct gl_pipeline_stage _radeon_render_stage; extern const struct gl_pipeline_stage _radeon_tcl_stage; @@ -165,18 +166,10 @@ &_tnl_texgen_stage, &_tnl_texture_transform_stage, - /* Try again to go to tcl? - * - no good for asymmetric-twoside (do with multipass) - * - no good for asymmetric-unfilled (do with multipass) - * - good for material - * - good for texgen - * - need to manipulate a bit of state - * - * - worth it/not worth it? - */ - - /* Else do them here. + /* Scale texture rectangle to 0..1. */ + &_radeon_texrect_stage, + &_radeon_render_stage, &_tnl_render_stage, /* FALLBACK: */ 0, @@ -387,6 +380,8 @@ _math_matrix_set_identity( &rmesa->tmpmat ); driInitExtensions( ctx, card_extensions, GL_TRUE ); + if( rmesa->dri.drmMinor >= 9 || getenv( "RADEON_RECTANGLE_FORCE_ENABLE")) /* FIXME! a.s. */ + _mesa_enable_extension( ctx, "GL_NV_texture_rectangle"); radeonInitDriverFuncs( ctx ); radeonInitIoctlFuncs( ctx ); radeonInitStateFuncs( ctx ); Index: radeon_context.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v retrieving revision 1.28 diff -u -r1.28 radeon_context.h --- radeon_context.h 13 May 2003 21:46:39 -0000 1.28 +++ radeon_context.h 10 Jun 2003 15:37:49 -0000 @@ -259,6 +259,11 @@ #define TEX_PP_BORDER_COLOR 8 #define TEX_STATE_SIZE 9 +#define TXR_CMD_0 0 /* rectangle textures */ +#define TXR_PP_TEX_SIZE 1 /* 0x1d04, 0x1d0c for NPOT! */ +#define TXR_PP_TEX_PITCH 2 /* 0x1d08, 0x1d10 for NPOT! */ +#define TXR_STATE_SIZE 3 + #define ZBS_CMD_0 0 #define ZBS_SE_ZBIAS_FACTOR 1 #define ZBS_SE_ZBIAS_CONSTANT 2 @@ -422,6 +427,7 @@ struct radeon_state_atom grd; /* guard band clipping */ struct radeon_state_atom fog; struct radeon_state_atom glt; + struct radeon_state_atom txr[2]; /* for NPOT */ }; struct radeon_state { Index: radeon_ioctl.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v retrieving revision 1.44 diff -u -r1.44 radeon_ioctl.c --- radeon_ioctl.c 21 May 2003 17:32:09 -0000 1.44 +++ radeon_ioctl.c 10 Jun 2003 15:37:49 -0000 @@ -389,6 +389,73 @@ #endif } +/* using already shifted color_fmt! */ +void radeonEmitBlit( radeonContextPtr rmesa, /* FIXME: which drmMinor is required? */ + GLuint color_fmt, + GLuint src_pitch, + GLuint src_offset, + GLuint dst_pitch, + GLuint dst_offset, + GLint srcx, GLint srcy, + GLint dstx, GLint dsty, + GLuint w, GLuint h ) +{ + drmRadeonCmdHeader *cmd; + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n", + __FUNCTION__, + src_pitch, src_offset, srcx, srcy, + dst_pitch, dst_offset, dstx, dsty, + w, h); + + assert( (src_pitch & 63) == 0 ); + assert( (dst_pitch & 63) == 0 ); + assert( (src_offset & 1023) == 0 ); + assert( (dst_offset & 1023) == 0 ); + assert( w < (1<<16) ); + assert( h < (1<<16) ); + + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 8 * sizeof(int), + __FUNCTION__ ); + + + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3; + cmd[1].i = RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16); /* FIXME: is this the right package? */ + cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + color_fmt | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_MEMORY | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_WR_MSK_DIS ); + + cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10); + cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10); + cmd[5].i = (srcx << 16) | srcy; + cmd[6].i = (dstx << 16) | dsty; /* dst */ + cmd[7].i = (w << 16) | h; +} + + +void radeonEmitWait( radeonContextPtr rmesa, GLuint flags ) +{ + if (rmesa->dri.drmMinor >= 6) { + drmRadeonCmdHeader *cmd; + + assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) ); + + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 1 * sizeof(int), + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].wait.cmd_type = RADEON_CMD_WAIT; + cmd[0].wait.flags = flags; + } +} + static int radeonFlushCmdBufLocked( radeonContextPtr rmesa, const char * caller ) Index: radeon_ioctl.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v retrieving revision 1.11 diff -u -r1.11 radeon_ioctl.h --- radeon_ioctl.h 30 Apr 2003 01:50:51 -0000 1.11 +++ radeon_ioctl.h 10 Jun 2003 15:37:49 -0000 @@ -65,7 +65,17 @@ GLuint n, GLuint offset ); +extern void radeonEmitBlit( radeonContextPtr rmesa, + GLuint color_fmt, + GLuint src_pitch, + GLuint src_offset, + GLuint dst_pitch, + GLuint dst_offset, + GLint srcx, GLint srcy, + GLint dstx, GLint dsty, + GLuint w, GLuint h ); +extern void radeonEmitWait( radeonContextPtr rmesa, GLuint flags ); extern void radeonFlushCmdBuf( radeonContextPtr rmesa, const char * ); extern void radeonRefillCurrentDmaRegion( radeonContextPtr rmesa ); Index: radeon_sanity.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c,v retrieving revision 1.6 diff -u -r1.6 radeon_sanity.c --- radeon_sanity.c 30 Apr 2003 01:50:52 -0000 1.6 +++ radeon_sanity.c 10 Jun 2003 15:37:49 -0000 @@ -82,6 +82,61 @@ { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, + { 0, 4, "R200_PP_TXCBLEND_0" }, + { 0, 4, "R200_PP_TXCBLEND_1" }, + { 0, 4, "R200_PP_TXCBLEND_2" }, + { 0, 4, "R200_PP_TXCBLEND_3" }, + { 0, 4, "R200_PP_TXCBLEND_4" }, + { 0, 4, "R200_PP_TXCBLEND_5" }, + { 0, 4, "R200_PP_TXCBLEND_6" }, + { 0, 4, "R200_PP_TXCBLEND_7" }, + { 0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, + { 0, 6, "R200_PP_TFACTOR_0" }, + { 0, 4, "R200_SE_VTX_FMT_0" }, + { 0, 1, "R200_SE_VAP_CNTL" }, + { 0, 5, "R200_SE_TCL_MATRIX_SEL_0" }, + { 0, 5, "R200_SE_TCL_TEX_PROC_CTL_2" }, + { 0, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, + { 0, 6, "R200_PP_TXFILTER_0" }, + { 0, 6, "R200_PP_TXFILTER_1" }, + { 0, 6, "R200_PP_TXFILTER_2" }, + { 0, 6, "R200_PP_TXFILTER_3" }, + { 0, 6, "R200_PP_TXFILTER_4" }, + { 0, 6, "R200_PP_TXFILTER_5" }, + { 0, 1, "R200_PP_TXOFFSET_0" }, + { 0, 1, "R200_PP_TXOFFSET_1" }, + { 0, 1, "R200_PP_TXOFFSET_2" }, + { 0, 1, "R200_PP_TXOFFSET_3" }, + { 0, 1, "R200_PP_TXOFFSET_4" }, + { 0, 1, "R200_PP_TXOFFSET_5" }, + { 0, 1, "R200_SE_VTE_CNTL" }, + { 0, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, + { 0, 1, "R200_PP_TAM_DEBUG3" }, + { 0, 1, "R200_PP_CNTL_X" }, + { 0, 1, "R200_RB3D_DEPTHXY_OFFSET" }, + { 0, 1, "R200_RE_AUX_SCISSOR_CNTL" }, + { 0, 2, "R200_RE_SCISSOR_TL_0" }, + { 0, 2, "R200_RE_SCISSOR_TL_1" }, + { 0, 2, "R200_RE_SCISSOR_TL_2" }, + { 0, 1, "R200_SE_VAP_CNTL_STATUS" }, + { 0, 1, "R200_SE_VTX_STATE_CNTL" }, + { 0, 1, "R200_RE_POINTSIZE" }, + { 0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, + { 0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */ + { 0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */ + { 0, 1, "R200_PP_CUBIC_FACES_1" }, + { 0, 5, "R200_PP_CUBIC_OFFSET_F1_1" }, + { 0, 1, "R200_PP_CUBIC_FACES_2" }, + { 0, 5, "R200_PP_CUBIC_OFFSET_F1_2" }, + { 0, 1, "R200_PP_CUBIC_FACES_3" }, + { 0, 5, "R200_PP_CUBIC_OFFSET_F1_3" }, + { 0, 1, "R200_PP_CUBIC_FACES_4" }, + { 0, 5, "R200_PP_CUBIC_OFFSET_F1_4" }, + { 0, 1, "R200_PP_CUBIC_FACES_5" }, + { 0, 5, "R200_PP_CUBIC_OFFSET_F1_5" }, + { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" }, + { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" }, + { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_1" }, }; struct reg_names { @@ -168,7 +223,13 @@ { RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE, "RADEON_SE_TCL_SPECULAR_BLUE" }, { RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA, "RADEON_SE_TCL_SPECULAR_ALPHA" }, { RADEON_SE_TCL_SHININESS, "RADEON_SE_TCL_SHININESS" }, - { RADEON_SE_COORD_FMT, "RADEON_SE_COORD_FMT" } + { RADEON_SE_COORD_FMT, "RADEON_SE_COORD_FMT" }, + { RADEON_PP_TEX_SIZE_0, "RADEON_PP_TEX_SIZE_0" }, + { RADEON_PP_TEX_SIZE_1, "RADEON_PP_TEX_SIZE_1" }, + { RADEON_PP_TEX_SIZE_2, "RADEON_PP_TEX_SIZE_2" }, + { RADEON_PP_TEX_SIZE_0+4, "RADEON_PP_TEX_PITCH_0" }, + { RADEON_PP_TEX_SIZE_1+4, "RADEON_PP_TEX_PITCH_1" }, + { RADEON_PP_TEX_SIZE_2+4, "RADEON_PP_TEX_PITCH_2" }, }; static struct reg_names scalar_names[] = { Index: radeon_state_init.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c,v retrieving revision 1.10 diff -u -r1.10 radeon_state_init.c --- radeon_state_init.c 30 Apr 2003 01:50:54 -0000 1.10 +++ radeon_state_init.c 10 Jun 2003 15:37:50 -0000 @@ -134,6 +134,9 @@ TCL_CHECK( tcl_ucp5, (ctx->Transform.ClipPlanesEnabled & 0x20) ) TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled ) +CHECK( txr0, ctx->Texture.Unit[0]._ReallyEnabled ) +CHECK( txr1, ctx->Texture.Unit[1]._ReallyEnabled ) + /* Initialize the context's hardware state. @@ -246,6 +249,8 @@ ALLOC_STATE( lit[5], tcl_lit5, LIT_STATE_SIZE, "LIT/light-5", 1 ); ALLOC_STATE( lit[6], tcl_lit6, LIT_STATE_SIZE, "LIT/light-6", 1 ); ALLOC_STATE( lit[7], tcl_lit7, LIT_STATE_SIZE, "LIT/light-7", 1 ); + ALLOC_STATE( txr[0], txr0, TXR_STATE_SIZE, "TXR/txr-0", 0 ); + ALLOC_STATE( txr[1], txr1, TXR_STATE_SIZE, "TXR/txr-1", 0 ); /* Fill in the packet headers: @@ -268,6 +273,8 @@ rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT); rmesa->hw.mtl.cmd[MTL_CMD_0] = cmdpkt(RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED); + rmesa->hw.txr[0].cmd[TXR_CMD_0] = cmdpkt(RADEON_EMIT_PP_TEX_SIZE_0); + rmesa->hw.txr[1].cmd[TXR_CMD_0] = cmdpkt(RADEON_EMIT_PP_TEX_SIZE_1); rmesa->hw.grd.cmd[GRD_CMD_0] = cmdscl( RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 ); rmesa->hw.fog.cmd[FOG_CMD_0] = Index: radeon_swtcl.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c,v retrieving revision 1.18 diff -u -r1.18 radeon_swtcl.c --- radeon_swtcl.c 13 May 2003 21:46:39 -0000 1.18 +++ radeon_swtcl.c 10 Jun 2003 15:37:50 -0000 @@ -768,6 +768,132 @@ }; +/**************************************************************************/ + +/* Radeon 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 gl_pipeline_stage *stage ) +{ + struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + + if (rmesa->Fallback) + return GL_TRUE; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (!(ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT)) + continue; + + if (stage->changed_inputs & VERT_BIT_TEX(i)) { + struct gl_texture_object *texObj = ctx->Texture.Unit[i].CurrentRect; + struct gl_texture_image *texImage = texObj->Image[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; + + for (j = 0 ; j < VB->Count ; j++) { + out[j][0] = in[0] * iw; + out[j][1] = in[1] * ih; + in = (GLfloat *)((GLubyte *)in + instride); + } + } + + 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 gl_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 ); + + /* Now run the stage. + */ + stage->run = run_texrect_stage; + return stage->run( ctx, stage ); +} + + +static void check_texrect( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + GLuint flags = 0; + + if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_RECT_BIT) + flags |= VERT_BIT_TEX0; + + if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_RECT_BIT) + flags |= VERT_BIT_TEX1; + + stage->inputs = flags; + stage->outputs = flags; + stage->active = (flags != 0); +} + + +static void free_texrect_data( struct gl_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 = 0; + } +} + + +const struct gl_pipeline_stage _radeon_texrect_stage = +{ + "radeon texrect stage", /* name */ + _NEW_TEXTURE, /* check_state */ + _NEW_TEXTURE, /* run_state */ + GL_TRUE, /* active? */ + 0, /* inputs */ + 0, /* outputs */ + 0, /* changed_inputs */ + NULL, /* private data */ + free_texrect_data, /* destructor */ + check_texrect, /* check */ + alloc_texrect_data, /* run -- initially set to init */ +}; + /**************************************************************************/ @@ -1079,7 +1205,7 @@ "glEnable(GL_STENCIL) without hw stencil buffer", "glRenderMode(selection or feedback)", "glBlendEquation", - "glBlendFunc(mode != ADD)", + "glBlendFunc", "RADEON_NO_RAST", "Mixing GL_CLAMP_TO_BORDER and GL_CLAMP (or GL_MIRROR_CLAMP_ATI)" }; Index: radeon_tcl.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h,v retrieving revision 1.4 diff -u -r1.4 radeon_tcl.h --- radeon_tcl.h 30 Apr 2003 01:50:55 -0000 1.4 +++ radeon_tcl.h 10 Jun 2003 15:37:50 -0000 @@ -57,6 +57,9 @@ #define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ #define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ #define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ +#define RADEON_TCL_FALLBACK_TEXRECT_0 0x100 /* texture rectangle */ +#define RADEON_TCL_FALLBACK_TEXRECT_1 0x200 /* texture rectangle */ +#define RADEON_TCL_FALLBACK_TEXRECT_2 0x400 /* texture rectangle */ #define RADEON_MAX_TCL_VERTSIZE (15*4) Index: radeon_texmem.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c,v retrieving revision 1.17 diff -u -r1.17 radeon_texmem.c --- radeon_texmem.c 30 Apr 2003 01:50:55 -0000 1.17 +++ radeon_texmem.c 10 Jun 2003 15:37:50 -0000 @@ -43,6 +43,7 @@ #include "simple_list.h" #include "radeon_context.h" +#include "radeon_ioctl.h" #include "radeon_tex.h" @@ -76,6 +77,98 @@ * Texture image conversions */ + +static void radeonUploadRectSubImage( radeonContextPtr rmesa, + radeonTexObjPtr t, + struct gl_texture_image *texImage, + GLint x, GLint y, + GLint width, GLint height ) +{ + const struct gl_texture_format *texFormat = texImage->TexFormat; + int blit_format, dstPitch, done; + + switch ( texFormat->TexelBytes ) { + case 1: + blit_format = RADEON_GMC_DST_8BPP_CI; + break; + case 2: + blit_format = RADEON_GMC_DST_16BPP; + break; + case 4: + blit_format = RADEON_GMC_DST_32BPP; + break; + default: + fprintf( stderr, "radeonUploadRectSubImage: unknown blit_format (texelbytes=%d)\n", + texFormat->TexelBytes); + return; + } + + t->image[0][0].data = texImage->Data; + + /* Currently don't need to cope with small pitches. + */ + width = texImage->Width; + height = texImage->Height; + dstPitch = t->pp_txpitch + 32; + + { /* FIXME: prefer AGP-texturing if possible */ + /* Data not in agp memory, or bad pitch. + */ + for (done = 0; done < height ; ) { + struct radeon_dma_region region; + int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch ); + int src_pitch; + char *tex; + + src_pitch = texImage->RowStride * texFormat->TexelBytes; + + tex = (char *)texImage->Data + done * src_pitch; + + memset(®ion, 0, sizeof(region)); + radeonAllocDmaRegion( rmesa, ®ion, lines * dstPitch, 1024 ); + + /* Copy texdata to dma: + */ + if (0) + fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n", + __FUNCTION__, src_pitch, dstPitch); + + if (src_pitch == dstPitch) { + memcpy( region.address, tex, lines * src_pitch ); + } + else { + char *buf = region.address; + int i; + for (i = 0 ; i < lines ; i++) { + memcpy( buf, tex, src_pitch ); + buf += dstPitch; + tex += src_pitch; + } + } + + radeonEmitWait( rmesa, RADEON_WAIT_3D ); + + + + /* Blit to framebuffer + */ + radeonEmitBlit( rmesa, + blit_format, + dstPitch, GET_START( ®ion ), + dstPitch, t->bufAddr, + 0, 0, + 0, done, + width, lines ); + + radeonEmitWait( rmesa, RADEON_WAIT_2D ); + + radeonReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ ); + done += lines; + } + } +} + + /** * Upload the texture image associated with texture \a t at the specified * level at the address relative to \a start. @@ -138,6 +231,16 @@ return; } + + if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + assert(level == 0); + assert(hwlevel == 0); + if ( RADEON_DEBUG & DEBUG_TEXTURE ) + fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__); + radeonUploadRectSubImage( rmesa, t, texImage, x, y, width, height ); + return; + } + imageWidth = texImage->Width; imageHeight = texImage->Height; @@ -251,10 +354,12 @@ t->dirty_state = TEX_ALL; } + /* Let the world know we've used this memory recently. */ driUpdateTextureLRU( (driTextureObject *) t ); UNLOCK_HARDWARE( rmesa ); + /* Upload any images that are new */ if (t->base.dirty_images[face]) { Index: radeon_texstate.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v retrieving revision 1.17 diff -u -r1.17 radeon_texstate.c --- radeon_texstate.c 26 May 2003 19:48:52 -0000 1.17 +++ radeon_texstate.c 10 Jun 2003 15:37:50 -0000 @@ -147,6 +147,11 @@ log2Height = tObj->Image[firstLevel]->HeightLog2; log2Depth = 0; break; + case GL_TEXTURE_RECTANGLE_NV: + firstLevel = lastLevel = 0; + log2Width = log2Height = 1; /* ? */ + log2Depth = 0; + break; default: return; } @@ -177,6 +182,10 @@ if (texImage->IsCompressed) { size = texImage->CompressedSize; } + else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63) + & ~63) * texImage->Height; + } else { int w = texImage->Width * texImage->TexFormat->TexelBytes; if (w < 32) @@ -814,6 +823,7 @@ break; case GL_LUMINANCE: case GL_RGB: + case GL_YCBCR_MESA: color_combine = radeon_color_combine[unit][RADEON_REPLACE]; alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; break; @@ -837,6 +847,7 @@ break; case GL_RGB: case GL_LUMINANCE: + case GL_YCBCR_MESA: color_combine = radeon_color_combine[unit][RADEON_MODULATE]; alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; break; @@ -850,6 +861,7 @@ switch ( format ) { case GL_RGBA: case GL_RGB: + case GL_YCBCR_MESA: color_combine = radeon_color_combine[unit][RADEON_DECAL]; alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; break; @@ -872,6 +884,7 @@ case GL_RGB: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: + case GL_YCBCR_MESA: color_combine = radeon_color_combine[unit][RADEON_BLEND]; alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; break; @@ -895,6 +908,7 @@ case GL_RGB: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: + case GL_YCBCR_MESA: color_combine = radeon_color_combine[unit][RADEON_ADD]; alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; break; @@ -1262,9 +1276,16 @@ cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset; cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; - texobj->dirty_state &= ~(1<<unit); - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] ); + + if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] ); + txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */ + txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */ + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] ); + } + + texobj->dirty_state &= ~(1<<unit); } @@ -1461,6 +1482,33 @@ return GL_TRUE; } +static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; + + if (!(t->pp_txformat & RADEON_TXFORMAT_NON_POWER2)) { + t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; + t->base.dirty_images[0] = ~0; + } + + ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); + + if ( t->base.dirty_images[0] ) { + RADEON_FIREVERTICES( rmesa ); + radeonSetTexImages( rmesa, tObj ); + radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 ); + if ( !t->base.memBlock /* && !rmesa->prefer_agp_client_texturing FIXME */ ) { + fprintf(stderr, "%s: upload failed\n", __FUNCTION__); + return GL_FALSE; + } + } + + return GL_TRUE; +} + static GLboolean update_tex_common( GLcontext *ctx, int unit ) { @@ -1471,8 +1519,10 @@ GLenum format; /* Fallback if there's a texture border */ - if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) - return GL_FALSE; + if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) { + fprintf(stderr, "%s: border\n", __FUNCTION__); + return GL_FALSE; + } /* Update state if this is a different texture object to last * time. @@ -1542,7 +1592,15 @@ { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 0 ); + + if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) { + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 1 ); + + return (enable_tex_rect( ctx, unit ) && + update_tex_common( ctx, unit )); + } + else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { return (enable_tex_2d( ctx, unit ) && update_tex_common( ctx, unit )); }