r600g/compute Improve debugging output
[mesa.git] / src / gallium / drivers / softpipe / sp_state_shader.c
index 6acb57b3fe6d8cb8a367e1231e549ff961e8385e..eb4b6b1458ce68c907ff620997d1bf68c5e62d3a 100644 (file)
@@ -38,7 +38,6 @@
 #include "draw/draw_vs.h"
 #include "draw/draw_gs.h"
 #include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_exec.h"
 #include "tgsi/tgsi_scan.h"
 #include "tgsi/tgsi_parse.h"
 
@@ -158,8 +157,10 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
 
    softpipe->fs = fs;
 
-   if (fs == NULL)
-      softpipe->fs_variant = NULL;
+   /* This depends on the current fragment shader and must always be
+    * re-validated before use.
+    */
+   softpipe->fs_variant = NULL;
 
    if (state)
       draw_bind_fragment_shader(softpipe->draw,
@@ -180,13 +181,6 @@ softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
 
    assert(fs != softpipe->fs);
 
-   if (softpipe->fs_machine->Tokens == state->shader.tokens) {
-      /* unbind the shader from the tgsi executor if we're
-       * deleting it.
-       */
-      tgsi_exec_machine_bind_shader(softpipe->fs_machine, NULL, 0, NULL);
-   }
-
    /* delete variants */
    for (var = state->variants; var; var = next_var) {
       next_var = var->next;
@@ -198,7 +192,7 @@ softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
       draw_delete_fragment_shader(softpipe->draw, var->draw_shader);
 #endif
 
-      var->delete(var);
+      var->delete(var, softpipe->fs_machine);
    }
 
    draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
@@ -281,21 +275,25 @@ softpipe_create_gs_state(struct pipe_context *pipe,
    if (state == NULL )
       goto fail;
 
-   /* debug */
-   if (softpipe->dump_gs)
-      tgsi_dump(templ->tokens, 0);
+   state->shader = *templ;
 
-   /* copy shader tokens, the ones passed in will go away.
-    */
-   state->shader.tokens = tgsi_dup_tokens(templ->tokens);
-   if (state->shader.tokens == NULL)
-      goto fail;
+   if (templ->tokens) {
+      /* debug */
+      if (softpipe->dump_gs)
+         tgsi_dump(templ->tokens, 0);
 
-   state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
-   if (state->draw_data == NULL)
-      goto fail;
+      /* copy shader tokens, the ones passed in will go away.
+       */
+      state->shader.tokens = tgsi_dup_tokens(templ->tokens);
+      if (state->shader.tokens == NULL)
+         goto fail;
 
-   state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
+      state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
+      if (state->draw_data == NULL)
+         goto fail;
+
+      state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
+   }
 
    return state;
 
@@ -342,14 +340,27 @@ softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
 static void
 softpipe_set_constant_buffer(struct pipe_context *pipe,
                              uint shader, uint index,
-                             struct pipe_resource *constants)
+                             struct pipe_constant_buffer *cb)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
-   unsigned size = constants ? constants->width0 : 0;
-   const void *data = constants ? softpipe_resource(constants)->data : NULL;
+   struct pipe_resource *constants = cb ? cb->buffer : NULL;
+   unsigned size;
+   const void *data;
 
    assert(shader < PIPE_SHADER_TYPES);
 
+   if (cb && cb->user_buffer) {
+      constants = softpipe_user_buffer_create(pipe->screen,
+                                              (void *) cb->user_buffer,
+                                              cb->buffer_size,
+                                              PIPE_BIND_CONSTANT_BUFFER);
+   }
+
+   size = cb ? cb->buffer_size : 0;
+   data = constants ? softpipe_resource_data(constants) : NULL;
+   if (data)
+      data = (const char *) data + cb->buffer_offset;
+
    draw_flush(softpipe->draw);
 
    /* note: reference counting */
@@ -363,6 +374,10 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
    softpipe->const_buffer_size[shader][index] = size;
 
    softpipe->dirty |= SP_NEW_CONSTANTS;
+
+   if (cb && cb->user_buffer) {
+      pipe_resource_reference(&constants, NULL);
+   }
 }