gallium: use simple color pass-through fragment shader if textures don't exist
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 25 Apr 2008 21:23:21 +0000 (15:23 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 25 Apr 2008 21:24:07 +0000 (15:24 -0600)
If we run out of texture memory we may not have the texture needed by the
fragment shader.  If this happens, plug in a color passthrough shader.
So instead of crashing, we just don't see the texture.
GL_OUT_OF_MEMORY is raised, of course.

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

index 01c07dc26d3a959f7db22fbce9ddc3a979d35231..d15da5895ab05512c9b7a9b281c7ad77214bcca7 100644 (file)
 #include "st_cb_texture.h"
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
+#include "cso_cache/cso_context.h"
+#include "util/u_simple_shaders.h"
+
+
+static void *
+get_passthrough_fs(struct st_context *st)
+{
+   struct pipe_shader_state shader;
+
+   if (!st->passthrough_fs) {
+      st->passthrough_fs =
+         util_make_fragment_passthrough_shader(st->pipe, &shader);
+      free((void *) shader.tokens);
+   }
+
+   return st->passthrough_fs;
+}
 
 
 /**
@@ -49,6 +66,7 @@ update_textures(struct st_context *st)
 {
    struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
    GLuint su;
+   GLboolean missing_textures = GL_FALSE;
 
    st->state.num_textures = 0;
 
@@ -67,6 +85,7 @@ update_textures(struct st_context *st)
             retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
             if (!retval) {
                /* out of mem */
+               missing_textures = GL_TRUE;
                continue;
             }
 
@@ -79,8 +98,15 @@ update_textures(struct st_context *st)
       pipe_texture_reference(&st->state.sampler_texture[su], pt);
    }
 
-   st->pipe->set_sampler_textures(st->pipe, st->state.num_textures,
-                                  st->state.sampler_texture);
+   cso_set_sampler_textures(st->cso_context,
+                            st->state.num_textures,
+                            st->state.sampler_texture);
+
+   if (missing_textures) {
+      /* use a pass-through frag shader that uses no textures */
+      void *fs = get_passthrough_fs(st);
+      cso_set_fragment_shader_handle(st->cso_context, fs);
+   }
 }
 
 
index 2851770d4cae3cf0dfe7f6b33e5c8cb8681c196a..7e933a2b109e73f932e5e0b1eeae6beb06499ed7 100644 (file)
@@ -165,6 +165,8 @@ struct st_context
       struct pipe_buffer *vbuf;
    } clear;
 
+   void *passthrough_fs;  /**< simple pass-through frag shader */
+
    struct gen_mipmap_state *gen_mipmap;
    struct blit_state *blit;