st/mesa: fix fallout from xfb changes.
[mesa.git] / src / mesa / state_tracker / st_program.c
index 624586e6d67db6d58b38100490c2e3cfaa7b84df..94dc48971ec181e62e434d59dd5ae31b4e09e66b 100644 (file)
@@ -53,6 +53,7 @@
 #include "st_context.h"
 #include "st_program.h"
 #include "st_mesa_to_tgsi.h"
+#include "st_atifs_to_tgsi.h"
 #include "cso_cache/cso_context.h"
 
 
@@ -158,6 +159,9 @@ delete_basic_variant(struct st_context *st, struct st_basic_variant *v,
       case GL_GEOMETRY_PROGRAM_NV:
          cso_delete_geometry_shader(st->cso_context, v->driver_shader);
          break;
+      case GL_COMPUTE_PROGRAM_NV:
+         cso_delete_compute_shader(st->cso_context, v->driver_shader);
+         break;
       default:
          assert(!"this shouldn't occur");
       }
@@ -192,6 +196,30 @@ st_release_basic_variants(struct st_context *st, GLenum target,
 }
 
 
+/**
+ * Free all variants of a compute program.
+ */
+void
+st_release_cp_variants(struct st_context *st, struct st_compute_program *stcp)
+{
+   struct st_basic_variant **variants = &stcp->variants;
+   struct st_basic_variant *v;
+
+   for (v = *variants; v; ) {
+      struct st_basic_variant *next = v->next;
+      delete_basic_variant(st, v, stcp->Base.Base.Target);
+      v = next;
+   }
+
+   *variants = NULL;
+
+   if (stcp->tgsi.prog) {
+      ureg_free_tokens(stcp->tgsi.prog);
+      stcp->tgsi.prog = NULL;
+   }
+}
+
+
 /**
  * Translate a vertex program.
  */
@@ -546,10 +574,6 @@ st_translate_fragment_program(struct st_context *st,
          else
             interpLocation[slot] = TGSI_INTERPOLATE_LOC_CENTER;
 
-         if (stfp->Base.Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
-                                                 SYSTEM_BIT_SAMPLE_POS))
-            interpLocation[slot] = TGSI_INTERPOLATE_LOC_SAMPLE;
-
          switch (attr) {
          case VARYING_SLOT_POS:
             input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
@@ -788,7 +812,22 @@ st_translate_fragment_program(struct st_context *st,
 
       free_glsl_to_tgsi_visitor(stfp->glsl_to_tgsi);
       stfp->glsl_to_tgsi = NULL;
-   } else
+   } else if (stfp->ati_fs)
+      st_translate_atifs_program(ureg,
+                                 stfp->ati_fs,
+                                 &stfp->Base.Base,
+                                 /* inputs */
+                                 fs_num_inputs,
+                                 inputMapping,
+                                 input_semantic_name,
+                                 input_semantic_index,
+                                 interpMode,
+                                 /* outputs */
+                                 fs_num_outputs,
+                                 outputMapping,
+                                 fs_output_semantic_name,
+                                 fs_output_semantic_index);
+   else
       st_translate_mesa_program(st->ctx,
                                 TGSI_PROCESSOR_FRAGMENT,
                                 ureg,
@@ -826,6 +865,16 @@ st_create_fp_variant(struct st_context *st,
 
    assert(!(key->bitmap && key->drawpixels));
 
+   /* Fix texture targets and add fog for ATI_fs */
+   if (stfp->ati_fs) {
+      const struct tgsi_token *tokens = st_fixup_atifs(tgsi.tokens, key);
+
+      if (tokens)
+         tgsi.tokens = tokens;
+      else
+         fprintf(stderr, "mesa: cannot post-process ATI_fs\n");
+   }
+
    /* Emulate features. */
    if (key->clamp_color || key->persample_shading) {
       const struct tgsi_token *tokens;
@@ -835,9 +884,11 @@ st_create_fp_variant(struct st_context *st,
 
       tokens = tgsi_emulate(tgsi.tokens, flags);
 
-      if (tokens)
+      if (tokens) {
+         if (tgsi.tokens != stfp->tgsi.tokens)
+            tgsi_free_tokens(tgsi.tokens);
          tgsi.tokens = tokens;
-      else
+      else
          fprintf(stderr, "mesa: cannot emulate deprecated features\n");
    }
 
@@ -848,6 +899,7 @@ st_create_fp_variant(struct st_context *st,
       variant->bitmap_sampler = ffs(~stfp->Base.Base.SamplersUsed) - 1;
 
       tokens = st_get_bitmap_shader(tgsi.tokens,
+                                    st->internal_target,
                                     variant->bitmap_sampler,
                                     st->needs_texcoord_semantic,
                                     st->bitmap.tex_format ==
@@ -900,7 +952,7 @@ st_create_fp_variant(struct st_context *st,
                                      bias_const, key->pixelMaps,
                                      variant->drawpix_sampler,
                                      variant->pixelmap_sampler,
-                                     texcoord_const);
+                                     texcoord_const, st->internal_target);
 
       if (tokens) {
          if (tgsi.tokens != stfp->tgsi.tokens)
@@ -1271,6 +1323,7 @@ st_translate_geometry_program(struct st_context *st,
  */
 struct st_basic_variant *
 st_get_basic_variant(struct st_context *st,
+                     unsigned pipe_shader,
                      struct pipe_shader_state *tgsi,
                      struct st_basic_variant **variants)
 {
@@ -1293,7 +1346,22 @@ st_get_basic_variant(struct st_context *st,
       v = CALLOC_STRUCT(st_basic_variant);
       if (v) {
          /* fill in new variant */
-         v->driver_shader = pipe->create_gs_state(pipe, tgsi);
+         switch (pipe_shader) {
+         case PIPE_SHADER_TESS_CTRL:
+            v->driver_shader = pipe->create_tcs_state(pipe, tgsi);
+            break;
+         case PIPE_SHADER_TESS_EVAL:
+            v->driver_shader = pipe->create_tes_state(pipe, tgsi);
+            break;
+         case PIPE_SHADER_GEOMETRY:
+            v->driver_shader = pipe->create_gs_state(pipe, tgsi);
+            break;
+         default:
+            assert(!"unhandled shader type");
+            free(v);
+            return NULL;
+         }
+
          v->key = key;
 
          /* insert into list */
@@ -1378,6 +1446,74 @@ st_translate_tesseval_program(struct st_context *st,
 }
 
 
+/**
+ * Translate a compute program to create a new variant.
+ */
+bool
+st_translate_compute_program(struct st_context *st,
+                             struct st_compute_program *stcp)
+{
+   struct ureg_program *ureg;
+   struct pipe_shader_state prog;
+
+   ureg = ureg_create_with_screen(TGSI_PROCESSOR_COMPUTE, st->pipe->screen);
+   if (ureg == NULL)
+      return false;
+
+   st_translate_program_common(st, &stcp->Base.Base, stcp->glsl_to_tgsi, ureg,
+                               TGSI_PROCESSOR_COMPUTE, &prog);
+
+   stcp->tgsi.prog = prog.tokens;
+   stcp->tgsi.req_local_mem = stcp->Base.SharedSize;
+   stcp->tgsi.req_private_mem = 0;
+   stcp->tgsi.req_input_mem = 0;
+
+   free_glsl_to_tgsi_visitor(stcp->glsl_to_tgsi);
+   stcp->glsl_to_tgsi = NULL;
+   return true;
+}
+
+
+/**
+ * Get/create compute program variant.
+ */
+struct st_basic_variant *
+st_get_cp_variant(struct st_context *st,
+                  struct pipe_compute_state *tgsi,
+                  struct st_basic_variant **variants)
+{
+   struct pipe_context *pipe = st->pipe;
+   struct st_basic_variant *v;
+   struct st_basic_variant_key key;
+
+   memset(&key, 0, sizeof(key));
+   key.st = st->has_shareable_shaders ? NULL : st;
+
+   /* Search for existing variant */
+   for (v = *variants; v; v = v->next) {
+      if (memcmp(&v->key, &key, sizeof(key)) == 0) {
+         break;
+      }
+   }
+
+   if (!v) {
+      /* create new */
+      v = CALLOC_STRUCT(st_basic_variant);
+      if (v) {
+         /* fill in new variant */
+         v->driver_shader = pipe->create_compute_state(pipe, tgsi);
+         v->key = key;
+
+         /* insert into list */
+         v->next = *variants;
+         *variants = v;
+      }
+   }
+
+   return v;
+}
+
+
 /**
  * Vert/Geom/Frag programs have per-context variants.  Free all the
  * variants attached to the given program which match the given context.
@@ -1433,14 +1569,17 @@ destroy_program_variants(struct st_context *st, struct gl_program *target)
    case GL_GEOMETRY_PROGRAM_NV:
    case GL_TESS_CONTROL_PROGRAM_NV:
    case GL_TESS_EVALUATION_PROGRAM_NV:
+   case GL_COMPUTE_PROGRAM_NV:
       {
          struct st_geometry_program *gp = (struct st_geometry_program*)target;
          struct st_tessctrl_program *tcp = (struct st_tessctrl_program*)target;
          struct st_tesseval_program *tep = (struct st_tesseval_program*)target;
+         struct st_compute_program *cp = (struct st_compute_program*)target;
          struct st_basic_variant **variants =
             target->Target == GL_GEOMETRY_PROGRAM_NV ? &gp->variants :
             target->Target == GL_TESS_CONTROL_PROGRAM_NV ? &tcp->variants :
             target->Target == GL_TESS_EVALUATION_PROGRAM_NV ? &tep->variants :
+            target->Target == GL_COMPUTE_PROGRAM_NV ? &cp->variants :
             NULL;
          struct st_basic_variant *v, **prevPtr = variants;
 
@@ -1497,6 +1636,7 @@ destroy_shader_program_variants_cb(GLuint key, void *data, void *userData)
    case GL_GEOMETRY_SHADER:
    case GL_TESS_CONTROL_SHADER:
    case GL_TESS_EVALUATION_SHADER:
+   case GL_COMPUTE_SHADER:
       {
          destroy_program_variants(st, shader->Program);
       }
@@ -1587,19 +1727,19 @@ st_precompile_shader_variant(struct st_context *st,
 
    case GL_TESS_CONTROL_PROGRAM_NV: {
       struct st_tessctrl_program *p = (struct st_tessctrl_program *)prog;
-      st_get_basic_variant(st, &p->tgsi, &p->variants);
+      st_get_basic_variant(st, PIPE_SHADER_TESS_CTRL, &p->tgsi, &p->variants);
       break;
    }
 
    case GL_TESS_EVALUATION_PROGRAM_NV: {
       struct st_tesseval_program *p = (struct st_tesseval_program *)prog;
-      st_get_basic_variant(st, &p->tgsi, &p->variants);
+      st_get_basic_variant(st, PIPE_SHADER_TESS_EVAL, &p->tgsi, &p->variants);
       break;
    }
 
    case GL_GEOMETRY_PROGRAM_NV: {
       struct st_geometry_program *p = (struct st_geometry_program *)prog;
-      st_get_basic_variant(st, &p->tgsi, &p->variants);
+      st_get_basic_variant(st, PIPE_SHADER_GEOMETRY, &p->tgsi, &p->variants);
       break;
    }
 
@@ -1613,6 +1753,12 @@ st_precompile_shader_variant(struct st_context *st,
       break;
    }
 
+   case GL_COMPUTE_PROGRAM_NV: {
+      struct st_compute_program *p = (struct st_compute_program *)prog;
+      st_get_cp_variant(st, &p->tgsi, &p->variants);
+      break;
+   }
+
    default:
       assert(0);
    }