summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuj Phogat <anuj.phogat@gmail.com>2012-08-31 13:51:39 -0700
committerIan Romanick <ian.d.romanick@intel.com>2012-10-07 20:38:14 -0700
commitad4b3b93ded960c22388c7bc3ba14d32b30b8f1d (patch)
tree07dd388f2a88c75bd80fa4f1e8ee209f91816346
parent7851d398def2df3f6836a500d67123eed50f3943 (diff)
_mesa_meta_GenerateMipmap: Support all texture targets by generating shaders at runtime
This is a squash for the following 7 commits. The first introduces the functionality, and the remaining six fix various bugs. Patch 1: _mesa_meta_GenerateMipmap: Support all texture targets by generating shaders at runtime 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 V2: Removed the code for integer textures as ARB is planning to disallow automatic mipmap generation for integer textures. Now using ralloc_asprintf in setup_glsl_generate_mipmap(). NOTE: This is a candidate for stable branches. Signed-off-by: Anuj Phogat <anuj.phogat@gmail.com> Reviewed-by: Brian Paul <brianp@vmware.com> (cherry picked from commit 299acac849eb8506de9760c94c6e8e8b1046d909) Patch 2: _mesa_meta_GenerateMipmap: Generate separate shaders for glsl 120 / 130 glsl version of _mesa_meta_GenerateMipmap() would require separate shaders for glsl 120 and 130. V2: Removed the code for integer textures as ARB is planning to disallow automatic mipmap generation for integer textures. NOTE: This is a candidate for stable branches. Signed-off-by: Anuj Phogat <anuj.phogat@gmail.com> Reviewed-by: Brian Paul <brianp@vmware.com> (cherry picked from commit 15bf3103b48a5928321fe56fbb3ed28a0f314418) Patch 3: 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> (cherry picked from commit eb1d87fb945783448cc40ad43c9cd4d98002d424) Patch 4: meta: make mem_ctx non-global. I can't see any external users, and this is a global symbol, Reviewed-by: Matt Turner <mattst88@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com> (cherry picked from commit 36639ec6e9a2758e344235fbdc1450719d8851e3) Patch 5: meta: Remove unsafe global mem_ctx pointer NOTE: This is a candidate for the 9.0 branch. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com> (cherry picked from commit ab097dde0c958dd8b1c06a07ef8913512753760c) Patch 6: meta: Rearrange shader creation in setup_glsl_generate_mipmap The diff looks weird, but this moves the code from the first 'if (ctx->Const.GLSLVersion < 130)' block down into the second block. It also moves some variable decalarations closer to their use. NOTE: This is a candidate for the 9.0 branch. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com> (cherry picked from commit 3308c079bd00e9b9aa546f5214ce197a904d059b) Patch 7: meta: Don't use GLSL 1.30 shader on OpenGL ES 2 Fixes GLES2 CoverageGL conformance test. NOTE: This is a candidate for the 9.0 branch. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com> (cherry picked from commit 0242381f06edb09dcf0eaacd6d26ccd8584700cc)
-rw-r--r--src/mesa/drivers/common/meta.c206
1 files changed, 169 insertions, 37 deletions
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index fe452cf8e53..5f0b4784e07 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -76,7 +76,7 @@
#include "drivers/common/meta.h"
#include "main/enums.h"
#include "main/glformats.h"
-
+#include "../glsl/ralloc.h"
/** Return offset in bytes of the field within a vertex struct */
#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
@@ -272,6 +272,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()
@@ -284,9 +294,14 @@ struct gen_mipmap_state
GLuint Sampler;
GLuint ShaderProg;
GLuint IntegerShaderProg;
+ 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;
};
-
/**
* State for texture decompression
*/
@@ -2979,7 +2994,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];
@@ -3008,31 +3023,62 @@ setup_ff_generate_mipmap(struct gl_context *ctx,
}
+static struct glsl_sampler *
+setup_texture_sampler(GLenum target, struct gen_mipmap_state *mipmap)
+{
+ switch(target) {
+ case GL_TEXTURE_1D:
+ mipmap->sampler_1d.type = "sampler1D";
+ mipmap->sampler_1d.func = "texture1D";
+ mipmap->sampler_1d.texcoords = "texCoords.x";
+ return &mipmap->sampler_1d;
+ case GL_TEXTURE_2D:
+ 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.
+ */
+ mipmap->sampler_3d.type = "sampler3D";
+ mipmap->sampler_3d.func = "texture3D";
+ mipmap->sampler_3d.texcoords = "texCoords";
+ return &mipmap->sampler_3d;
+ case GL_TEXTURE_CUBE_MAP:
+ mipmap->sampler_cubemap.type = "samplerCube";
+ mipmap->sampler_cubemap.func = "textureCube";
+ mipmap->sampler_cubemap.texcoords = "texCoords";
+ return &mipmap->sampler_cubemap;
+ case GL_TEXTURE_1D_ARRAY:
+ 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:
+ 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;
+ }
+}
+
+
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;
+ const char *vs_source;
- static const char *vs_source =
- "attribute vec2 position;\n"
- "attribute vec3 textureCoords;\n"
- "varying vec3 texCoords;\n"
- "void main()\n"
- "{\n"
- " texCoords = textureCoords;\n"
- " gl_Position = vec4(position, 0.0, 1.0);\n"
- "}\n";
- static const char *fs_source =
- "uniform sampler2D tex2d;\n"
- "varying vec3 texCoords;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = texture2D(tex2d, texCoords.xy);\n"
- "}\n";
-
static const char *vs_int_source =
"#version 130\n"
"in vec2 position;\n"
@@ -3053,24 +3099,96 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
"{\n"
" out_color = texture(tex2d, texCoords.xy);\n"
"}\n";
+ char *fs_source;
GLuint vs, fs;
+ void *mem_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 */
+ 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->API == API_OPENGLES2 || ctx->Const.GLSLVersion < 130) {
+ const char *fs_template;
+ const char *extension_mode;
+
+ vs_source =
+ "attribute vec2 position;\n"
+ "attribute vec3 textureCoords;\n"
+ "varying vec3 texCoords;\n"
+ "void main()\n"
+ "{\n"
+ " texCoords = textureCoords;\n"
+ " gl_Position = vec4(position, 0.0, 1.0);\n"
+ "}\n";
+ fs_template =
+ "#extension GL_EXT_texture_array : %s\n"
+ "uniform %s texSampler;\n"
+ "varying vec3 texCoords;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = %s(texSampler, %s);\n"
+ "}\n";
+
+ extension_mode = ((target == GL_TEXTURE_1D_ARRAY) ||
+ (target == GL_TEXTURE_2D_ARRAY)) ?
+ "require" : "disable";
+
+ fs_source = ralloc_asprintf(mem_ctx, fs_template,
+ extension_mode, sampler->type,
+ sampler->func, sampler->texcoords);
+ }
+ else {
+ const char *fs_template;
+
+ vs_source =
+ "#version 130\n"
+ "in vec2 position;\n"
+ "in vec3 textureCoords;\n"
+ "out vec3 texCoords;\n"
+ "void main()\n"
+ "{\n"
+ " texCoords = textureCoords;\n"
+ " gl_Position = vec4(position, 0.0, 1.0);\n"
+ "}\n";
+ fs_template =
+ "#version 130\n"
+ "uniform %s texSampler;\n"
+ "in vec3 texCoords;\n"
+ "out %s out_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " out_color = texture(texSampler, %s);\n"
+ "}\n";
+
+ fs_source = ralloc_asprintf(mem_ctx, fs_template,
+ sampler->type, "vec4",
+ sampler->texcoords);
+ }
vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source);
fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source);
@@ -3085,6 +3203,8 @@ 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) ||
_mesa_is_gles3(ctx)){
@@ -3118,8 +3238,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);
@@ -3177,7 +3309,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);