draw: implement TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION
authorMarek Olšák <marek.olsak@amd.com>
Mon, 17 Nov 2014 21:30:31 +0000 (22:30 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 9 Dec 2014 11:27:10 +0000 (12:27 +0100)
Required by Nine. Tested with util_run_tests.
It's added to softpipe, llvmpipe, and r300g/swtcl.

Tested-by: David Heidelberg <david@ixit.cz>
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
src/gallium/auxiliary/draw/draw_vs.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/softpipe/sp_screen.c

index 7bd2d393bf6518ea245447db2272827a71f991a1..04cf5b7630e984ebd72568a7d306d88edeee7382 100644 (file)
@@ -254,21 +254,48 @@ void draw_set_zs_format(struct draw_context *draw, enum pipe_format format)
 }
 
 
-static void update_clip_flags( struct draw_context *draw )
+static bool
+draw_is_vs_window_space(struct draw_context *draw)
 {
-   draw->clip_xy = !draw->driver.bypass_clip_xy;
+   if (draw->vs.vertex_shader) {
+      struct tgsi_shader_info *info = &draw->vs.vertex_shader->info;
+
+      return info->properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION] != 0;
+   }
+   return false;
+}
+
+
+void
+draw_update_clip_flags(struct draw_context *draw)
+{
+   bool window_space = draw_is_vs_window_space(draw);
+
+   draw->clip_xy = !draw->driver.bypass_clip_xy && !window_space;
    draw->guard_band_xy = (!draw->driver.bypass_clip_xy &&
                           draw->driver.guard_band_xy);
    draw->clip_z = (!draw->driver.bypass_clip_z &&
-                   draw->rasterizer && draw->rasterizer->depth_clip);
+                   draw->rasterizer && draw->rasterizer->depth_clip) &&
+                  !window_space;
    draw->clip_user = draw->rasterizer &&
-                     draw->rasterizer->clip_plane_enable != 0;
+                     draw->rasterizer->clip_plane_enable != 0 &&
+                     !window_space;
    draw->guard_band_points_xy = draw->guard_band_xy ||
                                 (draw->driver.bypass_clip_points &&
                                 (draw->rasterizer &&
                                  draw->rasterizer->point_tri_clip));
 }
 
+
+void
+draw_update_viewport_flags(struct draw_context *draw)
+{
+   bool window_space = draw_is_vs_window_space(draw);
+
+   draw->bypass_viewport = window_space || draw->identity_viewport;
+}
+
+
 /**
  * Register new primitive rasterization/rendering state.
  * This causes the drawing pipeline to be rebuilt.
@@ -282,7 +309,7 @@ void draw_set_rasterizer_state( struct draw_context *draw,
 
       draw->rasterizer = raster;
       draw->rast_handle = rast_handle;
-      update_clip_flags(draw);
+      draw_update_clip_flags(draw);
    }
 }
 
@@ -309,7 +336,7 @@ void draw_set_driver_clipping( struct draw_context *draw,
    draw->driver.bypass_clip_z = bypass_clip_z;
    draw->driver.guard_band_xy = guard_band_xy;
    draw->driver.bypass_clip_points = bypass_clip_points;
-   update_clip_flags(draw);
+   draw_update_clip_flags(draw);
 }
 
 
@@ -363,6 +390,7 @@ void draw_set_viewport_states( struct draw_context *draw,
        viewport->translate[0] == 0.0f &&
        viewport->translate[1] == 0.0f &&
        viewport->translate[2] == 0.0f);
+   draw_update_viewport_flags(draw);
 }
 
 
index dbaece3ab352466a68ac2f3f4352c93361c5ab03..832607251d7f7e3d16cd7096775655aeda30a147 100644 (file)
@@ -1836,7 +1836,7 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
    key->clip_xy = llvm->draw->clip_xy;
    key->clip_z = llvm->draw->clip_z;
    key->clip_user = llvm->draw->clip_user;
-   key->bypass_viewport = llvm->draw->identity_viewport;
+   key->bypass_viewport = llvm->draw->bypass_viewport;
    key->clip_halfz = llvm->draw->rasterizer->clip_halfz;
    key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE);
    key->ucp_enable = llvm->draw->rasterizer->clip_plane_enable;
index 37045ebb029613a9ad1f5a10e50cf5114c694c35..7b893cb2692aaa5420d55ad483d18ddca62fa7e4 100644 (file)
@@ -252,6 +252,7 @@ struct draw_context
 
    struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
    boolean identity_viewport;
+   boolean bypass_viewport;
 
    /** Vertex shader state */
    struct {
@@ -478,6 +479,9 @@ void
 draw_stats_clipper_primitives(struct draw_context *draw,
                               const struct draw_prim_info *prim_info);
 
+void draw_update_clip_flags(struct draw_context *draw);
+void draw_update_viewport_flags(struct draw_context *draw);
+
 /** 
  * Return index i from the index buffer.
  * If the index buffer would overflow we return the
index c675321f35568b689f02477ae1f58543a34673d7..50f438ce0b19fda2e38cd050d8c49bcb89cd2a1c 100644 (file)
@@ -95,7 +95,7 @@ fse_prepare(struct draw_pt_middle_end *middle,
    fse->key.nr_elements = MAX2(fse->key.nr_outputs,     /* outputs - translate to hw format */
                                fse->key.nr_inputs);     /* inputs - fetch from api format */
 
-   fse->key.viewport = !draw->identity_viewport;
+   fse->key.viewport = !draw->bypass_viewport;
    fse->key.clip = draw->clip_xy || draw->clip_z || draw->clip_user;
    fse->key.const_vbuffers = 0;
 
index f518deef27dcee75925f84598d5f598f7deba330..5af845ff93823a4ac36dbe146f2f2f237510e739 100644 (file)
@@ -117,7 +117,7 @@ fetch_pipeline_prepare(struct draw_pt_middle_end *middle,
                             draw->clip_user,
                             point_clip ? draw->guard_band_points_xy :
                                          draw->guard_band_xy,
-                            draw->identity_viewport,
+                            draw->bypass_viewport,
                             draw->rasterizer->clip_halfz,
                             (draw->vs.edgeflag_output ? TRUE : FALSE) );
 
index cc837366ae970554ea1570b7109668af96779d6e..0dfafdca51a0c475db1ef8e1dc2f44c767873c28 100644 (file)
@@ -162,7 +162,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
                             draw->clip_user,
                             point_clip ? draw->guard_band_points_xy :
                                          draw->guard_band_xy,
-                            draw->identity_viewport,
+                            draw->bypass_viewport,
                             draw->rasterizer->clip_halfz,
                             (draw->vs.edgeflag_output ? TRUE : FALSE) );
 
index f24354e9d5164f906f09bc80ba92fe90e5413df0..1501942eb443ab8a5123cc71b87e8a98ac60c074 100644 (file)
@@ -122,6 +122,8 @@ draw_bind_vertex_shader(struct draw_context *draw,
       draw->vs.clipdistance_output[0] = dvs->clipdistance_output[0];
       draw->vs.clipdistance_output[1] = dvs->clipdistance_output[1];
       dvs->prepare( dvs, draw );
+      draw_update_clip_flags(draw);
+      draw_update_viewport_flags(draw);
    }
    else {
       draw->vs.vertex_shader = NULL;
index e10e83ebb1d78062549f51a1c41a58f477de9b0f..6af43ccf58135ee456d610e92819d63b5a2b3122 100644 (file)
@@ -252,7 +252,9 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TEXTURE_QUERY_LOD:
    case PIPE_CAP_SAMPLE_SHADING:
    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
+      return 0;
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
+      return 1;
    case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
    case PIPE_CAP_SAMPLER_VIEW_TARGET:
       return 0;
index 47616f65f3d38638471f23a58630644a5bffec94..e653eab184edaa08e575e0253ae8e92060c1f96d 100644 (file)
@@ -177,7 +177,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_FAKE_SW_MSAA:
         case PIPE_CAP_SAMPLE_SHADING:
         case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
-        case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
         case PIPE_CAP_DRAW_INDIRECT:
         case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
         case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
@@ -187,6 +186,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         /* SWTCL-only features. */
         case PIPE_CAP_PRIMITIVE_RESTART:
         case PIPE_CAP_USER_VERTEX_BUFFERS:
+        case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
             return !r300screen->caps.has_tcl;
 
         /* HWTCL-only features / limitations. */
index 47126eff180505fda56fd31896433e1b8f6b20e6..57cd9b632df7426aac645df9880260ef3d8e2062 100644 (file)
@@ -196,7 +196,9 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TEXTURE_QUERY_LOD:
    case PIPE_CAP_SAMPLE_SHADING:
    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
+      return 0;
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
+      return 1;
    case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
    case PIPE_CAP_SAMPLER_VIEW_TARGET:
       return 0;