[Mesa-dev] [PATCH 7/8] meta: add _mesa_meta_DrawTex()

Chia-I Wu olvaffe at gmail.com
Wed Aug 31 19:41:47 PDT 2011


On Thu, Sep 1, 2011 at 4:04 AM, Ian Romanick <idr at freedesktop.org> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 08/30/2011 10:46 PM, Chia-I Wu wrote:
>> From: Chia-I Wu <olv at lunarg.com>
>>
>> It can be used for dd->DrawTex.
>
> My main concern about this is that we have exactly zero tests for this
> extension.  Before this is enabled in Intel drivers, I want there to be
> at least some test coverage.  I always have Keith Packard's adage, "Any
> code that isn't tested is broken." in the back of my mind... and I hate
> it when he's right. :)
I think you are right.  I will work on a piglit test before committing
this change (but likely not today).  There is a demo in demos repo
meanwhile if you want to play with it.

> There's one other comment below.  I was going to say more, but I decided
> I was wrong.
>
>> ---
>>  src/mesa/drivers/common/meta.c |  141 ++++++++++++++++++++++++++++++++++++++++
>>  src/mesa/drivers/common/meta.h |    3 +
>>  2 files changed, 144 insertions(+), 0 deletions(-)
>>
>> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
>> index 291d912..c772543 100644
>> --- a/src/mesa/drivers/common/meta.c
>> +++ b/src/mesa/drivers/common/meta.c
>> @@ -259,6 +259,17 @@ struct gen_mipmap_state
>>     GLuint FBO;
>>  };
>>
>> +
>> +/**
>> + * State for glDrawTex()
>> + */
>> +struct drawtex_state
>> +{
>> +   GLuint ArrayObj;
>> +   GLuint VBO;
>> +};
>> +
>> +
>>  #define MAX_META_OPS_DEPTH      2
>>  /**
>>   * All per-context meta state.
>> @@ -278,6 +289,7 @@ struct gl_meta_state
>>     struct drawpix_state DrawPix;  /**< For _mesa_meta_DrawPixels() */
>>     struct bitmap_state Bitmap;    /**< For _mesa_meta_Bitmap() */
>>     struct gen_mipmap_state Mipmap;    /**< For _mesa_meta_GenerateMipmap() */
>> +   struct drawtex_state DrawTex;  /**< For _mesa_meta_DrawTex() */
>>  };
>>
>>
>> @@ -2994,3 +3006,132 @@ _mesa_meta_CopyColorSubTable(struct gl_context *ctx,GLenum target, GLsizei start
>>
>>     free(buf);
>>  }
>> +
>> +
>> +/**
>> + * Meta implementation of ctx->Driver.DrawTex() in terms
>> + * of polygon rendering.
>> + */
>> +void
>> +_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
>> +                   GLfloat width, GLfloat height)
>> +{
>> +#if FEATURE_OES_draw_texture
>> +   struct drawtex_state *drawtex = &ctx->Meta->DrawTex;
>> +   struct vertex {
>> +      GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2];
>> +   };
>> +   struct vertex verts[4];
>> +   GLuint i;
>> +
>> +   _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
>> +                          MESA_META_SHADER |
>> +                          MESA_META_TRANSFORM |
>> +                          MESA_META_VERTEX |
>> +                          MESA_META_VIEWPORT));
>> +
>> +   if (drawtex->ArrayObj == 0) {
>> +      /* one-time setup */
>> +      GLint active_texture;
>> +
>> +      /* create vertex array object */
>> +      _mesa_GenVertexArrays(1, &drawtex->ArrayObj);
>> +      _mesa_BindVertexArray(drawtex->ArrayObj);
>> +
>> +      /* create vertex array buffer */
>> +      _mesa_GenBuffersARB(1, &drawtex->VBO);
>> +      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
>> +      _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
>> +                          NULL, GL_DYNAMIC_DRAW_ARB);
>> +
>> +      /* client active texture is not part of the array object */
>> +      active_texture = ctx->Array.ActiveTexture;
>> +
>> +      /* setup vertex arrays */
>> +      _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
>> +      _mesa_EnableClientState(GL_VERTEX_ARRAY);
>> +      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
>> +         _mesa_ClientActiveTextureARB(GL_TEXTURE0 + i);
>> +         _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i]));
>> +         _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
>> +      }
>> +
>> +      /* restore client active texture */
>> +      _mesa_ClientActiveTextureARB(GL_TEXTURE0 + active_texture);
>> +   }
>> +   else {
>> +      _mesa_BindVertexArray(drawtex->ArrayObj);
>> +      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
>> +   }
>> +
>> +   /* vertex positions, texcoords */
>> +   {
>> +      const GLfloat x1 = x + width;
>> +      const GLfloat y1 = y + height;
>> +
>> +      z = CLAMP(z, 0.0, 1.0);
>> +      z = invert_z(z);
>> +
>> +      verts[0].x = x;
>> +      verts[0].y = y;
>> +      verts[0].z = z;
>> +
>> +      verts[1].x = x1;
>> +      verts[1].y = y;
>> +      verts[1].z = z;
>> +
>> +      verts[2].x = x1;
>> +      verts[2].y = y1;
>> +      verts[2].z = z;
>> +
>> +      verts[3].x = x;
>> +      verts[3].y = y1;
>> +      verts[3].z = z;
>> +
>> +      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
>> +         const struct gl_texture_object *texObj;
>> +         const struct gl_texture_image *texImage;
>> +         GLfloat s, t, s1, t1;
>> +         GLuint tw, th;
>> +
>> +         if (!ctx->Texture.Unit[i]._ReallyEnabled) {
>> +            GLuint j;
>> +            for (j = 0; j < 4; j++) {
>> +               verts[j].st[i][0] = 0.0f;
>> +               verts[j].st[i][1] = 0.0f;
>> +            }
>> +            continue;
>> +         }
>> +
>> +         texObj = ctx->Texture.Unit[i]._Current;
>> +         texImage = texObj->Image[0][texObj->BaseLevel];
>> +         tw = texImage->Width2;
>> +         th = texImage->Height2;
>> +
>> +         s = (GLfloat) texObj->CropRect[0] / tw;
>> +         t = (GLfloat) texObj->CropRect[1] / th;
>> +         s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw;
>> +         t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th;
>> +
>> +         verts[0].st[i][0] = s;
>> +         verts[0].st[i][1] = t;
>> +
>> +         verts[1].st[i][0] = s1;
>> +         verts[1].st[i][1] = t;
>> +
>> +         verts[2].st[i][0] = s1;
>> +         verts[2].st[i][1] = t1;
>> +
>> +         verts[3].st[i][0] = s;
>> +         verts[3].st[i][1] = t1;
>> +      }
>> +
>> +      _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
>> +   }
>> +
>> +   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
>> +
>> +   _mesa_meta_end(ctx);
>> +#else
>
> The #else is unnecessary.
Ah, right.  Will do.
>> +#endif /* FEATURE_OES_draw_texture */
>> +}
>> diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h
>> index ac20e37..b52687f 100644
>> --- a/src/mesa/drivers/common/meta.h
>> +++ b/src/mesa/drivers/common/meta.h
>> @@ -140,5 +140,8 @@ _mesa_meta_CopyConvolutionFilter2D(struct gl_context *ctx, GLenum target,
>>                                     GLenum internalFormat, GLint x, GLint y,
>>                                     GLsizei width, GLsizei height);
>>
>> +extern void
>> +_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
>> +                   GLfloat width, GLfloat height);
>>
>>  #endif /* META_H */
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.11 (GNU/Linux)
> Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAk5ek7YACgkQX1gOwKyEAw8a/ACdE65S0mS9hWfjusMuYzG/ug7p
> CRQAn11HRq0TRvf5mMo+A7FJcqdArpIH
> =CdOW
> -----END PGP SIGNATURE-----
>



-- 
olv at LunarG.com


More information about the mesa-dev mailing list