From: Dave Airlie Date: Sun, 4 Dec 2005 00:37:35 +0000 (+0000) Subject: Fix r300 rectangular texture upload and swtcl coordinate fixing same as radeon X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f93feb7aedc194f3fa04fa2216b2a215548b2e4e;p=mesa.git Fix r300 rectangular texture upload and swtcl coordinate fixing same as radeon sw tcl --- diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 96d6e3ee87b..8d2165106aa 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -428,6 +428,9 @@ void r300InitCmdBuf(r300ContextPtr r300) ALLOC_STATE( tex.format, variable, mtu+1, "tex_format", 0 ); r300->hw.tex.format.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FORMAT_0, 0); + ALLOC_STATE( tex.pitch, variable, mtu+1, "tex_pitch", 0 ); + r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_PITCH_0, 0); + ALLOC_STATE( tex.offset, variable, mtu+1, "tex_offset", 0 ); r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_OFFSET_0, 0); @@ -513,6 +516,7 @@ void r300InitCmdBuf(r300ContextPtr r300) insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown1); insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.size); insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.format); + insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.pitch); insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.offset); insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown4); insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.border_color); diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 9c089e40053..4ff30cc0c63 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -123,6 +123,7 @@ const struct dri_extension card_extensions[] = { extern struct tnl_pipeline_stage _r300_render_stage; extern struct tnl_pipeline_stage _r300_tcl_stage; +extern const struct tnl_pipeline_stage _r300_texrect_stage; static const struct tnl_pipeline_stage *r300_pipeline[] = { @@ -153,6 +154,8 @@ 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, diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 5d6ebe27aad..695609d33c9 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -177,10 +177,11 @@ struct r300_tex_obj { /* Six, for the cube faces */ + GLuint pitch; /* this isn't sent to hardware just used in calculations */ /* hardware register values */ /* Note that R200 has 8 registers per texture and R300 only 7 */ GLuint filter; - GLuint pitch; /* one of the unknown registers.. unknown 1 ?*/ + GLuint pitch_reg; GLuint size; /* npot only */ GLuint format; GLuint offset; /* Image location in the card's address space. @@ -481,6 +482,7 @@ struct r300_hw_state { struct r300_state_atom unknown1; struct r300_state_atom size; struct r300_state_atom format; + struct r300_state_atom pitch; struct r300_state_atom offset; struct r300_state_atom unknown4; struct r300_state_atom border_color; diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index fba79126365..a65a200d83c 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -793,6 +793,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_FORMAT_YUV_MODE 0x00800000 +#define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */ #define R300_TX_OFFSET_0 0x4540 /* BEGIN: Guess from R200 */ # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 5e7ce544d42..232a0645ba2 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -882,3 +882,108 @@ const struct tnl_pipeline_stage _r300_tcl_stage = { NULL, 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 cc60785aac1..f4d588af526 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1019,6 +1019,7 @@ void r300_setup_textures(GLcontext *ctx) R300_STATECHANGE(r300, tex.unknown1); R300_STATECHANGE(r300, tex.size); R300_STATECHANGE(r300, tex.format); + R300_STATECHANGE(r300, tex.pitch); R300_STATECHANGE(r300, tex.offset); R300_STATECHANGE(r300, tex.unknown4); R300_STATECHANGE(r300, tex.border_color); @@ -1070,6 +1071,7 @@ void r300_setup_textures(GLcontext *ctx) r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size; r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format; //fprintf(stderr, "t->format=%08x\n", t->format); + r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0+i]=t->pitch_reg; r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=t->offset; r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0; r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0+i]=t->pp_border_color; @@ -1080,6 +1082,7 @@ void r300_setup_textures(GLcontext *ctx) ((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->packet0.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.size.cmd)->packet0.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->packet0.count = max_texture_unit+1; + ((drm_r300_cmd_header_t*)r300->hw.tex.pitch.cmd)->packet0.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->packet0.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->packet0.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.border_color.cmd)->packet0.count = max_texture_unit+1; diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c index 64fed681f1e..f334880f27f 100644 --- a/src/mesa/drivers/dri/r300/r300_texmem.c +++ b/src/mesa/drivers/dri/r300/r300_texmem.c @@ -183,7 +183,7 @@ static void r300UploadRectSubImage(r300ContextPtr rmesa, */ width = texImage->Width; height = texImage->Height; - dstPitch = t->pitch + 32; + dstPitch = t->pitch; if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) { /* In this case, could also use GART texturing. This is diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index c06fadaa5e2..9cbef9b8008 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -243,6 +243,7 @@ static void r300SetTexImages(r300ContextPtr rmesa, } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height; + blitWidth = 64 / texelBytes; } else { int w = (texImage->Width * texelBytes + 31) & ~31; size = w * texImage->Height * texImage->Depth; @@ -363,8 +364,7 @@ static void r300SetTexImages(r300ContextPtr rmesa, } t->size = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << R300_TX_WIDTHMASK_SHIFT) - |((tObj->Image[0][t->base.firstLevel]->Height - 1) << R300_TX_HEIGHTMASK_SHIFT) - |((log2Width>log2Height)?log2Width:log2Height)<Image[0][t->base.firstLevel]->Height - 1) << R300_TX_HEIGHTMASK_SHIFT)); /* Only need to round to nearest 32 for textures, but the blitter * requires 64-byte aligned pitches, and we may/may not need the @@ -373,11 +373,19 @@ static void r300SetTexImages(r300ContextPtr rmesa, if (baseImage->IsCompressed) t->pitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); - else + else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + unsigned int align = blitWidth - 1; + t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width * + texelBytes) + 63) & ~(63); + t->size |= R300_TX_SIZE_TXPITCH_EN; + t->pitch_reg = (((tObj->Image[0][t->base.firstLevel]->Width) + align) & ~align) - 1; + } + else { + t->size |= ((log2Width>log2Height)?log2Width:log2Height)<pitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); - t->pitch -= 32; + } t->dirty_state = TEX_ALL;