mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 13:10:10 +01:00
meta: Add on demand compilation of per target shader programs
A call to glGenerateMipmap() follows the generation of a relevant shader program in setup_glsl_generate_mipmap(). To support all texture targets and to avoid compiling shaders everytime, per target shader programs are compiled on demand and saved for the next call. Fixes float-texture(mipmap.manual): See Comment 6: https://bugs.freedesktop.org/show_bug.cgi?id=54296 NOTE: This is a candidate for stable branches. Signed-off-by: Anuj Phogat <anuj.phogat@gmail.com> Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
parent
8ed9aaea51
commit
eb1d87fb94
1 changed files with 84 additions and 57 deletions
|
|
@ -269,6 +269,16 @@ struct bitmap_state
|
|||
struct temp_texture Tex; /**< separate texture from other meta ops */
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
GLuint shader_prog;
|
||||
};
|
||||
|
||||
/**
|
||||
* State for _mesa_meta_generate_mipmap()
|
||||
|
|
@ -281,16 +291,12 @@ struct gen_mipmap_state
|
|||
GLuint Sampler;
|
||||
GLuint ShaderProg;
|
||||
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;
|
||||
struct glsl_sampler sampler_1d;
|
||||
struct glsl_sampler sampler_2d;
|
||||
struct glsl_sampler sampler_3d;
|
||||
struct glsl_sampler sampler_cubemap;
|
||||
struct glsl_sampler sampler_1d_array;
|
||||
struct glsl_sampler sampler_2d_array;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2977,46 +2983,47 @@ setup_ff_generate_mipmap(struct gl_context *ctx,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_texture_sampler(GLenum target, struct glsl_sampler *sampler)
|
||||
static struct glsl_sampler *
|
||||
setup_texture_sampler(GLenum target, struct gen_mipmap_state *mipmap)
|
||||
{
|
||||
switch(target) {
|
||||
case GL_TEXTURE_1D:
|
||||
sampler->type = "sampler1D";
|
||||
sampler->func = "texture1D";
|
||||
sampler->texcoords = "texCoords.x";
|
||||
break;
|
||||
mipmap->sampler_1d.type = "sampler1D";
|
||||
mipmap->sampler_1d.func = "texture1D";
|
||||
mipmap->sampler_1d.texcoords = "texCoords.x";
|
||||
return &mipmap->sampler_1d;
|
||||
case GL_TEXTURE_2D:
|
||||
sampler->type = "sampler2D";
|
||||
sampler->func = "texture2D";
|
||||
sampler->texcoords = "texCoords.xy";
|
||||
break;
|
||||
mipmap->sampler_2d.type = "sampler2D";
|
||||
mipmap->sampler_2d.func = "texture2D";
|
||||
mipmap->sampler_2d.texcoords = "texCoords.xy";
|
||||
return &mipmap->sampler_2d;
|
||||
case GL_TEXTURE_3D:
|
||||
/* Code for mipmap generation with 3D textures is not used yet.
|
||||
* It's a sw fallback.
|
||||
*/
|
||||
sampler->type = "sampler3D";
|
||||
sampler->func = "texture3D";
|
||||
sampler->texcoords = "texCoords";
|
||||
break;
|
||||
mipmap->sampler_3d.type = "sampler3D";
|
||||
mipmap->sampler_3d.func = "texture3D";
|
||||
mipmap->sampler_3d.texcoords = "texCoords";
|
||||
return &mipmap->sampler_3d;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
sampler->type = "samplerCube";
|
||||
sampler->func = "textureCube";
|
||||
sampler->texcoords = "texCoords";
|
||||
break;
|
||||
mipmap->sampler_cubemap.type = "samplerCube";
|
||||
mipmap->sampler_cubemap.func = "textureCube";
|
||||
mipmap->sampler_cubemap.texcoords = "texCoords";
|
||||
return &mipmap->sampler_cubemap;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
sampler->type = "sampler1DArray";
|
||||
sampler->func = "texture1DArray";
|
||||
sampler->texcoords = "texCoords.xy";
|
||||
break;
|
||||
mipmap->sampler_1d_array.type = "sampler1DArray";
|
||||
mipmap->sampler_1d_array.func = "texture1DArray";
|
||||
mipmap->sampler_1d_array.texcoords = "texCoords.xy";
|
||||
return &mipmap->sampler_1d_array;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
sampler->type = "sampler2DArray";
|
||||
sampler->func = "texture2DArray";
|
||||
sampler->texcoords = "texCoords";
|
||||
break;
|
||||
mipmap->sampler_2d_array.type = "sampler2DArray";
|
||||
mipmap->sampler_2d_array.func = "texture2DArray";
|
||||
mipmap->sampler_2d_array.texcoords = "texCoords";
|
||||
return &mipmap->sampler_2d_array;
|
||||
default:
|
||||
_mesa_problem(NULL, "Unexpected texture target 0x%x in"
|
||||
" setup_texture_sampler()\n", target);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3029,7 +3036,7 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
|
|||
struct vertex {
|
||||
GLfloat x, y, tex[3];
|
||||
};
|
||||
struct glsl_sampler sampler;
|
||||
struct glsl_sampler *sampler;
|
||||
const char *vs_source;
|
||||
const char *fs_template;
|
||||
|
||||
|
|
@ -3099,24 +3106,31 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
|
|||
}
|
||||
|
||||
/* Check if already initialized */
|
||||
if (mipmap->ArrayObj != 0)
|
||||
return;
|
||||
/* create vertex array object */
|
||||
_mesa_GenVertexArrays(1, &mipmap->ArrayObj);
|
||||
_mesa_BindVertexArray(mipmap->ArrayObj);
|
||||
if (mipmap->ArrayObj == 0) {
|
||||
|
||||
/* create vertex array buffer */
|
||||
_mesa_GenBuffersARB(1, &mipmap->VBO);
|
||||
_mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
|
||||
/* create vertex array object */
|
||||
_mesa_GenVertexArrays(1, &mipmap->ArrayObj);
|
||||
_mesa_BindVertexArray(mipmap->ArrayObj);
|
||||
|
||||
/* setup vertex arrays */
|
||||
_mesa_VertexAttribPointerARB(0, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(struct vertex), OFFSET(x));
|
||||
_mesa_VertexAttribPointerARB(1, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof(struct vertex), OFFSET(tex));
|
||||
/* create vertex array buffer */
|
||||
_mesa_GenBuffersARB(1, &mipmap->VBO);
|
||||
_mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
|
||||
|
||||
/* setup vertex arrays */
|
||||
_mesa_VertexAttribPointerARB(0, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(struct vertex), OFFSET(x));
|
||||
_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);
|
||||
sampler = setup_texture_sampler(target, mipmap);
|
||||
assert(sampler != NULL);
|
||||
if (sampler->shader_prog != 0) {
|
||||
mipmap->ShaderProg = sampler->shader_prog;
|
||||
return;
|
||||
}
|
||||
|
||||
mem_ctx = ralloc_context(NULL);
|
||||
|
||||
if (ctx->Const.GLSLVersion < 130) {
|
||||
|
|
@ -3125,13 +3139,13 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
|
|||
"require" : "disable";
|
||||
|
||||
fs_source = ralloc_asprintf(mem_ctx, fs_template,
|
||||
extension_mode, sampler.type,
|
||||
sampler.func, sampler.texcoords);
|
||||
extension_mode, sampler->type,
|
||||
sampler->func, sampler->texcoords);
|
||||
}
|
||||
else {
|
||||
fs_source = ralloc_asprintf(mem_ctx, fs_template,
|
||||
sampler.type, "vec4",
|
||||
sampler.texcoords);
|
||||
sampler->type, "vec4",
|
||||
sampler->texcoords);
|
||||
}
|
||||
|
||||
vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source);
|
||||
|
|
@ -3147,6 +3161,7 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
|
|||
_mesa_EnableVertexAttribArrayARB(0);
|
||||
_mesa_EnableVertexAttribArrayARB(1);
|
||||
link_program_with_debug(ctx, mipmap->ShaderProg);
|
||||
sampler->shader_prog = mipmap->ShaderProg;
|
||||
ralloc_free(mem_ctx);
|
||||
|
||||
if ((_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130) ||
|
||||
|
|
@ -3181,8 +3196,20 @@ meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx,
|
|||
mipmap->ArrayObj = 0;
|
||||
_mesa_DeleteBuffersARB(1, &mipmap->VBO);
|
||||
mipmap->VBO = 0;
|
||||
_mesa_DeleteObjectARB(mipmap->ShaderProg);
|
||||
mipmap->ShaderProg = 0;
|
||||
|
||||
_mesa_DeleteObjectARB(mipmap->sampler_1d.shader_prog);
|
||||
_mesa_DeleteObjectARB(mipmap->sampler_2d.shader_prog);
|
||||
_mesa_DeleteObjectARB(mipmap->sampler_3d.shader_prog);
|
||||
_mesa_DeleteObjectARB(mipmap->sampler_cubemap.shader_prog);
|
||||
_mesa_DeleteObjectARB(mipmap->sampler_1d_array.shader_prog);
|
||||
_mesa_DeleteObjectARB(mipmap->sampler_2d_array.shader_prog);
|
||||
|
||||
mipmap->sampler_1d.shader_prog = 0;
|
||||
mipmap->sampler_2d.shader_prog = 0;
|
||||
mipmap->sampler_3d.shader_prog = 0;
|
||||
mipmap->sampler_cubemap.shader_prog = 0;
|
||||
mipmap->sampler_1d_array.shader_prog = 0;
|
||||
mipmap->sampler_2d_array.shader_prog = 0;
|
||||
|
||||
if (mipmap->IntegerShaderProg) {
|
||||
_mesa_DeleteObjectARB(mipmap->IntegerShaderProg);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue