st/mesa: fix transform feedback of unsubscripted gl_ClipDistance array
authorMarcin Slusarz <marcin.slusarz@gmail.com>
Sat, 16 Jun 2012 18:30:14 +0000 (20:30 +0200)
committerMarcin Slusarz <marcin.slusarz@gmail.com>
Wed, 20 Jun 2012 19:16:20 +0000 (21:16 +0200)
gl_ClipDistance needs special treatment in form of lowering pass
which transforms gl_ClipDistance representation from float[] to
vec4[]. There are 2 implementations - at glsl linker level (enabled
by LowerClipDistance option) and at glsl_to_tgsi level (enabled
unconditionally for gallium drivers). Second implementation is
incomplete - it does not take into account transform feedback (see
commit 642e5b413e0890b2070ba78fde42db381eaf02e5 "mesa: Fix transform
feedback of unsubscripted gl_ClipDistance array" for details).

There are 2 possible fixes:
- adding transform feedback support into glsl_to_tgsi version
- ripping gl_ClipDistance support from glsl_to_tgsi and enabling
  gl_ClipDistance lowering on glsl linker side

This patch implements 2nd option. All it does is:
- reverts most of the commit 59be691638200797583bce39a83f641d30d97492
  "st/mesa: add support for gl_ClipDistance"
- changes LowerClipDistance to true

Fixes Piglit tests "EXT_transform_feedback/builtin-varyings
gl_ClipDistance[{2,3,4,5,6,7,8}]-no-subscript" at least on nv50
and evergreen cards.

src/mesa/state_tracker/st_extensions.c
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index 17f271f02c1693d7bb7f784678f76340e4ee6f18..dacad9bfb9190df81afd62270a91be4e141e3c2d 100644 (file)
@@ -222,6 +222,7 @@ void st_init_limits(struct st_context *st)
          options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536);
       else
          options->MaxUnrollIterations = 255; /* SM3 limit */
+      options->LowerClipDistance = true;
    }
 
    /* PIPE_SHADER_CAP_MAX_INPUTS for the FS specifies the maximum number
index 5802b52b7493c4c87ffbc3c8714417b786fdf22f..b6abe84ac189b5b93e97dfcc54eb09e8334475eb 100644 (file)
@@ -304,7 +304,6 @@ public:
    int samplers_used;
    bool indirect_addr_temps;
    bool indirect_addr_consts;
-   int num_clip_distances;
    
    int glsl_version;
    bool native_integers;
@@ -2825,7 +2824,6 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
    samplers_used = 0;
    indirect_addr_temps = false;
    indirect_addr_consts = false;
-   num_clip_distances = 0;
    glsl_version = 0;
    native_integers = false;
    mem_ctx = ralloc_context(NULL);
@@ -4593,17 +4591,9 @@ st_translate_program(
       }
 
       for (i = 0; i < numOutputs; i++) {
-         if (outputSemanticName[i] == TGSI_SEMANTIC_CLIPDIST) {
-            int mask = ((1 << (program->num_clip_distances - 4*outputSemanticIndex[i])) - 1) & TGSI_WRITEMASK_XYZW;
-            t->outputs[i] = ureg_DECL_output_masked(ureg,
-                                                    outputSemanticName[i],
-                                                    outputSemanticIndex[i],
-                                                    mask);
-         } else {
-            t->outputs[i] = ureg_DECL_output(ureg,
-                                             outputSemanticName[i],
-                                             outputSemanticIndex[i]);
-         }
+         t->outputs[i] = ureg_DECL_output(ureg,
+                                          outputSemanticName[i],
+                                          outputSemanticIndex[i]);
       }
       if (passthrough_edgeflags)
          emit_edgeflags(t);
@@ -4759,8 +4749,7 @@ out:
 static struct gl_program *
 get_mesa_program(struct gl_context *ctx,
                  struct gl_shader_program *shader_program,
-                 struct gl_shader *shader,
-                 int num_clip_distances)
+                 struct gl_shader *shader)
 {
    glsl_to_tgsi_visitor* v = new glsl_to_tgsi_visitor();
    struct gl_program *prog;
@@ -4800,7 +4789,6 @@ get_mesa_program(struct gl_context *ctx,
    v->options = options;
    v->glsl_version = ctx->Const.GLSLVersion;
    v->native_integers = ctx->Const.NativeIntegers;
-   v->num_clip_distances = num_clip_distances;
 
    _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
                                               prog->Parameters);
@@ -4925,25 +4913,6 @@ get_mesa_program(struct gl_context *ctx,
    return prog;
 }
 
-/**
- * Searches through the IR for a declaration of gl_ClipDistance and returns the
- * declared size of the gl_ClipDistance array.  Returns 0 if gl_ClipDistance is
- * not declared in the IR.
- */
-int get_clip_distance_size(exec_list *ir)
-{
-   foreach_iter (exec_list_iterator, iter, *ir) {
-      ir_instruction *inst = (ir_instruction *)iter.get();
-      ir_variable *var = inst->as_variable();
-      if (var == NULL) continue;
-      if (!strcmp(var->name, "gl_ClipDistance")) {
-         return var->type->length;
-      }
-   }
-   
-   return 0;
-}
-
 extern "C" {
 
 struct gl_shader *
@@ -4982,7 +4951,6 @@ st_new_shader_program(struct gl_context *ctx, GLuint name)
 GLboolean
 st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 {
-   int num_clip_distances[MESA_SHADER_TYPES];
    assert(prog->LinkStatus);
 
    for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
@@ -4994,11 +4962,6 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
       const struct gl_shader_compiler_options *options =
             &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)];
 
-      /* We have to determine the length of the gl_ClipDistance array before
-       * the array is lowered to two vec4s by lower_clip_distance().
-       */
-      num_clip_distances[i] = get_clip_distance_size(ir);
-
       do {
          unsigned what_to_lower = MOD_TO_FRACT | DIV_TO_MUL_RCP |
             EXP_TO_EXP2 | LOG_TO_LOG2;
@@ -5020,7 +4983,6 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
           || progress;
 
          progress = lower_quadop_vector(ir, false) || progress;
-         progress = lower_clip_distance(ir) || progress;
 
          if (options->MaxIfDepth == 0)
             progress = lower_discard(ir) || progress;
@@ -5055,8 +5017,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
       if (prog->_LinkedShaders[i] == NULL)
          continue;
 
-      linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i],
-                                     num_clip_distances[i]);
+      linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
 
       if (linked_prog) {
         static const GLenum targets[] = {