gallium/util: fix glClear with MRT by making the FS write to all cbufs
authorMarek Olšák <maraeo@gmail.com>
Mon, 14 Jan 2013 16:07:58 +0000 (17:07 +0100)
committerMarek Olšák <maraeo@gmail.com>
Tue, 15 Jan 2013 15:47:18 +0000 (16:47 +0100)
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/util/u_simple_shaders.c
src/gallium/auxiliary/util/u_simple_shaders.h
src/gallium/state_trackers/vega/renderer.c
src/gallium/tests/trivial/tri.c
src/mesa/state_tracker/st_atom_shader.c
src/mesa/state_tracker/st_cb_clear.c

index 5f0134d7014f7b8f04a56b6a7c813e021bb243ca..7e3666122bf660f3b7116e06866216e6219f0e0e 100644 (file)
@@ -316,13 +316,39 @@ util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
 
 
 /**
- * Make simple fragment color pass-through shader.
+ * Make simple fragment color pass-through shader that replicates OUT[0]
+ * to all bound colorbuffers.
  */
 void *
-util_make_fragment_passthrough_shader(struct pipe_context *pipe)
+util_make_fragment_passthrough_shader(struct pipe_context *pipe,
+                                      int input_semantic,
+                                      int input_interpolate)
 {
-   return util_make_fragment_cloneinput_shader(pipe, 1, TGSI_SEMANTIC_COLOR,
-                                               TGSI_INTERPOLATE_PERSPECTIVE);
+   static const char shader_templ[] =
+         "FRAG\n"
+         "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n"
+         "DCL IN[0], %s[0], %s\n"
+         "DCL OUT[0], COLOR[0]\n"
+
+         "MOV OUT[0], IN[0]\n"
+         "END\n";
+
+   char text[sizeof(shader_templ)+100];
+   struct tgsi_token tokens[1000];
+   struct pipe_shader_state state = {tokens};
+
+   sprintf(text, shader_templ, tgsi_semantic_names[input_semantic],
+           tgsi_interpolate_names[input_interpolate]);
+
+   if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
+      assert(0);
+      return NULL;
+   }
+#if 0
+   tgsi_dump(state.tokens, 0);
+#endif
+
+   return pipe->create_fs_state(pipe, &state);
 }
 
 
index e4ffde6521e11105a16209058eb06bfd972c2663..22b9cee4de655cfa61a0a08aebe3a339c8b4e6f9 100644 (file)
@@ -87,7 +87,9 @@ util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
 
 
 extern void *
-util_make_fragment_passthrough_shader(struct pipe_context *pipe);
+util_make_fragment_passthrough_shader(struct pipe_context *pipe,
+                                      int input_semantic,
+                                      int input_interpolate);
 
 
 extern void *
index 11d3b5a0779b04739598070017a092ffb914389e..61e3105323465a2db78ed4060d080c212642b600 100644 (file)
@@ -308,7 +308,8 @@ static void renderer_set_fs(struct renderer *r, RendererFs id)
 
       switch (id) {
       case RENDERER_FS_COLOR:
-         fs = util_make_fragment_passthrough_shader(r->pipe);
+         fs = util_make_fragment_passthrough_shader(r->pipe,
+                          TGSI_SEMANTIC_COLOR, TGSI_INTERPOLATE_PERSPECTIVE);
          break;
       case RENDERER_FS_TEXTURE:
          fs = util_make_fragment_tex_shader(r->pipe,
index ad88b869c8d45e4d476bf30d0daf09670933138e..9acf2e1628a79af1a0d4504e7983fad4de64f09c 100644 (file)
@@ -216,7 +216,8 @@ static void init_prog(struct program *p)
        }
 
        /* fragment shader */
-       p->fs = util_make_fragment_passthrough_shader(p->pipe);
+       p->fs = util_make_fragment_passthrough_shader(p->pipe,
+                    TGSI_SEMANTIC_COLOR, TGSI_INTERPOLATE_PERSPECTIVE);
 }
 
 static void close_prog(struct program *p)
index 45e7a117f5c3b5e4d778b2e78b7658b9d73a6f73..c1d7c80bb3a115f18a9f2631da9205c552730e29 100644 (file)
@@ -59,7 +59,8 @@ get_passthrough_fs(struct st_context *st)
 {
    if (!st->passthrough_fs) {
       st->passthrough_fs =
-         util_make_fragment_passthrough_shader(st->pipe);
+         util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_COLOR,
+                                               TGSI_INTERPOLATE_PERSPECTIVE);
    }
 
    return st->passthrough_fs;
index 5cf4c07f126d52fad9f40a95057e5a3ea1607570..aabea6335ff35a78cc6f85cb732836d68a79572d 100644 (file)
@@ -96,7 +96,9 @@ static INLINE void
 set_fragment_shader(struct st_context *st)
 {
    if (!st->clear.fs)
-      st->clear.fs = util_make_fragment_passthrough_shader(st->pipe);
+      st->clear.fs =
+         util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_COLOR,
+                                               TGSI_INTERPOLATE_CONSTANT);
 
    cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
 }