[Mesa-dev] [PATCH 1/2] _mesa_meta_GenerateMipmap: Support all texture targets by generating shaders at runtime

Anuj Phogat anuj.phogat at gmail.com
Wed Sep 5 10:55:10 PDT 2012


On Wed, Sep 5, 2012 at 7:58 AM, Brian Paul <brianp at vmware.com> wrote:
>
> On 09/04/2012 08:42 PM, Anuj Phogat wrote:
>>
>> glsl path of _mesa_meta_GenerateMipmap() function would require different fragment
>> shaders depending on the texture target. This patch adds the code to generate
>> appropriate fragment shader programs at run time.
>> Fixes https://bugs.freedesktop.org/show_bug.cgi?id=54296
>>
>> NOTE: This is a candidate for stable branches.
>>
>> Signed-off-by: Anuj Phogat<anuj.phogat at gmail.com>
>> ---
>>   src/mesa/drivers/common/meta.c |  100 +++++++++++++++++++++++++++++++++++----
>>   1 files changed, 89 insertions(+), 11 deletions(-)
>>
>> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
>> index 36672a7..7d701f4 100644
>> --- a/src/mesa/drivers/common/meta.c
>> +++ b/src/mesa/drivers/common/meta.c
>> @@ -286,6 +286,15 @@ struct gen_mipmap_state
>>      GLuint IntegerShaderProg;
>>   };
>>
>> +/**
>> + * State for GLSL texture sampler which is used to generate fragment
>> + * shader in _mesa_meta_generate_mipmap().
>> + */
>> +struct glsl_sampler {
>> +   const char *type;
>> +   const char *func;
>> +   const char *texcoords;
>> +};
>>
>>   /**
>>    * State for texture decompression
>> @@ -2974,7 +2983,7 @@ setup_texture_coords(GLenum faceTarget,
>>
>>   static void
>>   setup_ff_generate_mipmap(struct gl_context *ctx,
>> -                           struct gen_mipmap_state *mipmap)
>> +                         struct gen_mipmap_state *mipmap)
>>   {
>>      struct vertex {
>>         GLfloat x, y, tex[3];
>> @@ -3004,12 +3013,53 @@ setup_ff_generate_mipmap(struct gl_context *ctx,
>>
>>
>>   static void
>> +setup_texture_sampler(GLenum target, struct glsl_sampler *sampler)
>> +{
>> +   switch(target) {
>> +   case GL_TEXTURE_1D:
>> +      sampler->type = "sampler1D";
>> +      sampler->func = "texture1D";
>> +      sampler->texcoords = "texCoords.x";
>> +      break;
>> +   case GL_TEXTURE_2D:
>> +      sampler->type = "sampler2D";
>> +      sampler->func = "texture2D";
>> +      sampler->texcoords = "texCoords.xy";
>> +      break;
>> +   case GL_TEXTURE_3D:
>> +      sampler->type = "sampler3D";
>> +      sampler->func = "texture3D";
>> +      sampler->texcoords = "texCoords";
>> +      break;
>> +   case GL_TEXTURE_CUBE_MAP:
>> +      sampler->type = "samplerCube";
>> +      sampler->func = "textureCube";
>> +      sampler->texcoords = "texCoords";
>> +      break;
>> +   case GL_TEXTURE_1D_ARRAY:
>> +      sampler->type = "sampler1DARRAY";
>> +      sampler->texcoords = "texCoords.xy";
>> +      break;
>> +   case GL_TEXTURE_2D_ARRAY:
>> +      sampler->type = "sampler2DARRAY";
>> +      sampler->texcoords = "texCoords";
>> +      break;
>
>
> Don't you need to set sampler->func for the ARARY cases?
Yes. I have added the support for array textures in my 2nd patch.
Refer to: [PATCH 2/2] _mesa_meta_GenerateMipmap: Generate separate
shaders for glsl 120 / 130
> Also note that we don't support mipmap generation for 3D textures yet (it's a sw fallback) and I don't recall ever testing 1D/2D ARRAY mipmap generation.
1D/2D array textures are allowed in glGenerateMipmap(). I'll find some
time to add a piglit test case to verify their support.
It might be useful to keep the code for 3D textures, in case we want
to support them.

>> +   default:
>> +      /* unexpected texture target */
>> +      return;
>> +   }
>> +}
>> +
>> +
>> +static void
>>   setup_glsl_generate_mipmap(struct gl_context *ctx,
>> -                           struct gen_mipmap_state *mipmap)
>> +                           struct gen_mipmap_state *mipmap,
>> +                           GLenum target)
>>   {
>>      struct vertex {
>>         GLfloat x, y, tex[3];
>>      };
>> +   struct glsl_sampler sampler;
>>
>>      static const char *vs_source =
>>         "attribute vec2 position;\n"
>> @@ -3020,14 +3070,17 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
>>         "   texCoords = textureCoords;\n"
>>         "   gl_Position = vec4(position, 0.0, 1.0);\n"
>>         "}\n";
>> -   static const char *fs_source =
>> -      "uniform sampler2D tex2d;\n"
>> +   static const char *fs_template =
>> +      "#define SAMPLER_TYPE %s\n"
>> +      "#define SAMPLER_FUNCTION %s\n"
>> +      "#define TEX_COORDS %s\n"
>> +      "uniform SAMPLER_TYPE texSampler;\n"
>>         "varying vec3 texCoords;\n"
>>         "void main()\n"
>>         "{\n"
>> -      "   gl_FragColor = texture2D(tex2d, texCoords.xy);\n"
>> +      "   gl_FragColor = SAMPLER_FUNCTION(texSampler, TEX_COORDS);\n"
>>         "}\n";
>> -
>> +
>>      static const char *vs_int_source =
>>         "#version 130\n"
>>         "in vec2 position;\n"
>> @@ -3036,18 +3089,22 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
>>         "void main()\n"
>>         "{\n"
>>         "   texCoords = textureCoords;\n"
>> -      "   gl_Position = gl_Vertex;\n"
>> +      "   gl_Position = vec4(position, 0.0, 1.0);\n"
>>         "}\n";
>> -   static const char *fs_int_source =
>> +   static const char *fs_int_template =
>>         "#version 130\n"
>> -      "uniform isampler2D tex2d;\n"
>> +      "#define SAMPLER_TYPE i%s\n"
>> +      "#define TEX_COORDS %s\n"
>> +      "uniform SAMPLER_TYPE texSampler;\n"
>>         "in vec3 texCoords;\n"
>>         "out ivec4 out_color;\n"
>>         "\n"
>>         "void main()\n"
>>         "{\n"
>> -      "   out_color = texture(tex2d, texCoords.xy);\n"
>> +      "   out_color = texture(texSampler, TEX_COORDS);\n"
>>         "}\n";
>> +   char *fs_source, *fs_int_source;
>> +   unsigned fs_alloc_len;
>>      GLuint vs, fs;
>>
>>      /* Check if already initialized */
>> @@ -3067,6 +3124,15 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
>>      _mesa_VertexAttribPointerARB(1, 3, GL_FLOAT, GL_FALSE,
>>                                   sizeof(struct vertex), OFFSET(tex));
>>
>> +   /* Generate a fragment shader program appropriate for the texture target */
>> +   setup_texture_sampler(target,&sampler);
>> +   fs_alloc_len = strlen(fs_template) + strlen(sampler.type) +
>> +                  strlen(sampler.func) + strlen(sampler.texcoords) + 1;
>> +   fs_source = (char *) malloc(fs_alloc_len);
>> +
>> +   sprintf(fs_source, fs_template,
>> +           sampler.type, sampler.func, sampler.texcoords);
>> +
>>      vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source);
>>      fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source);
>>
>> @@ -3080,9 +3146,20 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
>>      _mesa_EnableVertexAttribArrayARB(0);
>>      _mesa_EnableVertexAttribArrayARB(1);
>>      link_program_with_debug(ctx, mipmap->ShaderProg);
>> +   free(fs_source);
>>
>>      if ((_mesa_is_desktop_gl(ctx)&&  ctx->Const.GLSLVersion>= 130) ||
>>
>>          _mesa_is_gles3(ctx)){
>> +      /* Generate a fragment shader program appropriate for the texture
>> +       * target
>> +       */
>> +      fs_alloc_len = strlen(fs_int_template) + strlen(sampler.type) +
>> +                     strlen(sampler.texcoords) + 1;
>> +      fs_int_source = (char *) malloc(fs_alloc_len);
>> +
>> +      sprintf(fs_int_source, fs_int_template,
>> +              sampler.type, sampler.texcoords);
>> +
>
>
> I think the ARB is leaning toward disallowing automatic mipmap generation for integer-valued textures.  So you might put that part on hold.
>
Code for the integer textures already exists in
_mesa_meta_GenerateMipmap() but it doesn't support all texture targets
at the moment. We might push this code to complete the missing
support, in case ARB hasn't yet reached any conclusion on integer
textures. All the code for integer textures in
_mesa_meta_GenerateMipmap()  can be later removed if ARB decides to
disallow them.
>
>
>>         vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source);
>>         fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source);
>>
>> @@ -3099,6 +3176,7 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
>>          * BindFragDataLocation to 0.
>>          */
>>         link_program_with_debug(ctx, mipmap->IntegerShaderProg);
>> +      free(fs_int_source);
>>      }
>>   }
>>
>> @@ -3172,7 +3250,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
>>       * GenerateMipmap function.
>>       */
>>      if (use_glsl_version) {
>> -      setup_glsl_generate_mipmap(ctx, mipmap);
>> +      setup_glsl_generate_mipmap(ctx, mipmap, target);
>>
>>         if (texObj->_IsIntegerFormat)
>>            _mesa_UseProgramObjectARB(mipmap->IntegerShaderProg);
>
>


More information about the mesa-dev mailing list