gallium: use a default texture in update_textures(), update_samplers() when needed
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 14 Aug 2008 21:38:09 +0000 (15:38 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 14 Aug 2008 21:44:28 +0000 (15:44 -0600)
The default texture is used when the current fragment shader has texture
sample instructions but the user has not provided/bound a texture.

src/mesa/state_tracker/st_atom_sampler.c
src/mesa/state_tracker/st_atom_texture.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_cb_texture.h
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h

index 3ba6a971f6f1dbdd1ec109d956f6f7b213b87f9c..cef61fb55c5e0cc9364704b1f46c68edeeb7d41d 100644 (file)
@@ -35,6 +35,7 @@
 #include "main/macros.h"
 
 #include "st_context.h"
+#include "st_cb_texture.h"
 #include "st_atom.h"
 #include "st_program.h"
 #include "pipe/p_context.h"
@@ -125,6 +126,8 @@ update_samplers(struct st_context *st)
 
    st->state.num_samplers = 0;
 
+   /*printf("%s samplers used = 0x%x\n", __FUNCTION__, fs->Base.Base.SamplersUsed);*/
+
    /* loop over sampler units (aka tex image units) */
    for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
       struct pipe_sampler_state *sampler = st->state.samplers + su;
@@ -136,8 +139,9 @@ update_samplers(struct st_context *st)
          const struct gl_texture_object *texobj
             = st->ctx->Texture.Unit[texUnit]._Current;
 
-         if (!texobj)
-            continue;
+         if (!texobj) {
+            texobj = st_get_default_texture(st);
+         }
 
          sampler->wrap_s = gl_wrap_to_sp(texobj->WrapS);
          sampler->wrap_t = gl_wrap_to_sp(texobj->WrapT);
@@ -184,11 +188,11 @@ update_samplers(struct st_context *st)
 
          st->state.num_samplers = su + 1;
 
-         /* XXX more sampler state here */
-
+         /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/
          cso_single_sampler(st->cso_context, su, sampler);
       }
       else {
+         /*printf("%s su=%u null\n", __FUNCTION__, su);*/
          cso_single_sampler(st->cso_context, su, NULL);
       }
    }
index 1ec671ed48fc9b436e356604f85751dad508bb7f..fb03766ff599cc4f0a9c59691a82eaac12105325 100644 (file)
@@ -49,6 +49,8 @@ update_textures(struct st_context *st)
 
    st->state.num_textures = 0;
 
+   /*printf("%s samplers used = 0x%x\n", __FUNCTION__, fprog->Base.SamplersUsed);*/
+
    for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) {
       struct pipe_texture *pt = NULL;
 
@@ -56,24 +58,34 @@ update_textures(struct st_context *st)
          const GLuint texUnit = fprog->Base.SamplerUnits[su];
          struct gl_texture_object *texObj
             = st->ctx->Texture.Unit[texUnit]._Current;
-         struct st_texture_object *stObj = st_texture_object(texObj);
-
-         if (texObj) {
-            GLboolean flush, retval;
+         struct st_texture_object *stObj;
+         GLboolean flush, retval;
 
-            retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
-            if (!retval) {
-               /* out of mem */
-               /* missing texture */
-               continue;
-            }
+         if (!texObj) {
+            texObj = st_get_default_texture(st);
+         }
+         stObj = st_texture_object(texObj);
 
-            st->state.num_textures = su + 1;
+         retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
+         if (!retval) {
+            /* out of mem */
+            continue;
          }
 
+         st->state.num_textures = su + 1;
+
          pt = st_get_stobj_texture(stObj);
       }
 
+      /*
+      if (pt) {
+         printf("%s su=%u non-null\n", __FUNCTION__, su);
+      }
+      else {
+         printf("%s su=%u null\n", __FUNCTION__, su);
+      }
+      */
+
       pipe_texture_reference(&st->state.sampler_texture[su], pt);
    }
 
index fceb260d708008267e8d7030c22571d0a16664a4..f291531f81cb0a0e25295cf1ce907d5428784aae 100644 (file)
@@ -1461,6 +1461,46 @@ st_finalize_texture(GLcontext *ctx,
 }
 
 
+/**
+ * Returns pointer to a default/dummy texture.
+ * This is typically used when the current shader has tex/sample instructions
+ * but the user has not provided a (any) texture(s).
+ */
+struct gl_texture_object *
+st_get_default_texture(struct st_context *st)
+{
+   if (!st->default_texture) {
+      static const GLenum target = GL_TEXTURE_2D;
+      GLubyte pixels[16][16][4];
+      struct gl_texture_object *texObj;
+      struct gl_texture_image *texImg;
+
+      texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target);
+
+      texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0);
+
+      _mesa_init_teximage_fields(st->ctx, target, texImg,
+                                 16, 16, 1, 0,  /* w, h, d, border */
+                                 GL_RGBA);
+
+      st_TexImage(st->ctx, 2, target,
+                  0, GL_RGBA,    /* level, intformat */
+                  16, 16, 1, 0,  /* w, h, d, border */
+                  GL_RGBA, GL_UNSIGNED_BYTE, pixels,
+                  &st->ctx->DefaultPacking,
+                  texObj, texImg,
+                  0, 0);
+
+      texObj->MinFilter = GL_NEAREST;
+      texObj->MagFilter = GL_NEAREST;
+      texObj->_Complete = GL_TRUE;
+
+      st->default_texture = texObj;
+   }
+   return st->default_texture;
+}
+
+
 void
 st_init_texture_functions(struct dd_function_table *functions)
 {
index 843745fcd67c02ef4dd67229130b7b044fe070e2..f1fe0339cdd72ff0e1f9b492a11c7b3252e5a51c 100644 (file)
@@ -37,6 +37,10 @@ st_finalize_texture(GLcontext *ctx,
                    GLboolean *needFlush);
 
 
+extern struct gl_texture_object *
+st_get_default_texture(struct st_context *st);
+
+
 extern void
 st_init_texture_functions(struct dd_function_table *functions);
 
index 6e4a376d44a15e7fd1eacd5cf53725d15a8a27b8..d014ace59fb4c6875f8ef9c64a7098b9b156ac01 100644 (file)
@@ -199,6 +199,11 @@ static void st_destroy_context_priv( struct st_context *st )
       }
    }
 
+   if (st->default_texture) {
+      st->ctx->Driver.DeleteTexture(st->ctx, st->default_texture);
+      st->default_texture = NULL;
+   }
+
    free( st );
 }
 
index 96333902a914c5d3eb19f60f03b58a99bf735d8d..4314d9af5c8aa311cfbec599407d8c8c5316f78b 100644 (file)
@@ -132,6 +132,8 @@ struct st_context
    struct st_vertex_program *vp;    /**< Currently bound vertex program */
    struct st_fragment_program *fp;  /**< Currently bound fragment program */
 
+   struct gl_texture_object *default_texture;
+
    struct {
       struct gl_program_cache *cache;
       struct st_fragment_program *program;  /**< cur pixel transfer prog */