Fix r300 rectangular texture upload and swtcl coordinate fixing same as radeon
authorDave Airlie <airliedfreedesktop.org>
Sun, 4 Dec 2005 00:37:35 +0000 (00:37 +0000)
committerDave Airlie <airliedfreedesktop.org>
Sun, 4 Dec 2005 00:37:35 +0000 (00:37 +0000)
sw tcl

src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_reg.h
src/mesa/drivers/dri/r300/r300_render.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_texmem.c
src/mesa/drivers/dri/r300/r300_texstate.c

index 96d6e3ee87b660f5e6dd0ae30a79ff1209622592..8d2165106aa4b649db4653b0617027d23e6d6efe 100644 (file)
@@ -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);
index 9c089e400534eff7bdd8455a8cbdc06169bc1a25..4ff30cc0c6384f3529604cc721fd38f95e72b98c 100644 (file)
@@ -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,
index 5d6ebe27aad227ce820cd28bf0b8cdf49f2487b4..695609d33c99b7e36274114ed4a53d1a71c210f6 100644 (file)
@@ -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;
index fba791263654b252f594601bb51f5a2bce77f8ff..a65a200d83c5740a9e76546756737054520911b2 100644 (file)
@@ -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)
index 5e7ce544d4258cd32ac8f9cb235f1a4720f3e45d..232a0645ba2afc7444cf80346d090b98d07493eb 100644 (file)
@@ -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
+};
+
index cc60785aac12c0c6fbb2ad0b15a3dfc57b0ce2b9..f4d588af526180f8156e2b474c513d4a1afffb1d 100644 (file)
@@ -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;
index 64fed681f1e155173bf6c567662925ff7b95a66d..f334880f27f47b288ddc05a7b986d53167c42524 100644 (file)
@@ -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
index c06fadaa5e25a2d5a647f2f1df60f60588df58f9..9cbef9b80083a970a8335f2788b7e81654c5d00d 100644 (file)
@@ -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)<<R300_TX_SIZE_SHIFT);
+                       |((tObj->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)<<R300_TX_SIZE_SHIFT;
                t->pitch =
                    ((tObj->Image[0][t->base.firstLevel]->Width *
                      texelBytes) + 63) & ~(63);
-       t->pitch -= 32;
+       }
 
        t->dirty_state = TEX_ALL;