I don't understand the need for lower_left_origin since D3D9 uses and upper-left window coordinate origin. Can you explain why this is needed?


On 10/20/2014 06:37 AM, David Heidelberger wrote:
From: Christoph Bumiller <e0425...@student.tuwien.ac.at>

D3D9 has different system coordinate, add neccessary infrastructure for it.

Signed-off-by: David Heidelberger <david.heidelber...@ixit.cz>
---
  src/gallium/auxiliary/util/u_dump_state.c   |  2 ++
  src/gallium/docs/source/context.rst         |  8 +++++-
  src/gallium/docs/source/cso/rasterizer.rst  | 38 ++++++++++++++++++++---------
  src/gallium/docs/source/screen.rst          |  2 ++
  src/gallium/include/pipe/p_defines.h        |  1 +
  src/gallium/include/pipe/p_state.h          |  1 +
  src/mesa/state_tracker/st_atom_rasterizer.c |  4 ++-
  src/mesa/state_tracker/st_atom_scissor.c    |  2 +-
  src/mesa/state_tracker/st_atom_viewport.c   |  2 +-
  src/mesa/state_tracker/st_cb_rasterpos.c    |  2 +-
  src/mesa/state_tracker/st_context.c         |  3 +++
  src/mesa/state_tracker/st_context.h         |  1 +
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp  |  7 ++++--
  src/mesa/state_tracker/st_mesa_to_tgsi.c    |  7 ++++--
  14 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_dump_state.c 
b/src/gallium/auxiliary/util/u_dump_state.c
index e6614d5..af53622 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -328,9 +328,11 @@ util_dump_rasterizer_state(FILE *stream, const struct 
pipe_rasterizer_state *sta
     util_dump_member(stream, bool, state, line_last_pixel);
     util_dump_member(stream, bool, state, flatshade_first);
     util_dump_member(stream, bool, state, half_pixel_center);
+   util_dump_member(stream, bool, state, lower_left_origin);
     util_dump_member(stream, bool, state, bottom_edge_rule);
     util_dump_member(stream, bool, state, rasterizer_discard);
     util_dump_member(stream, bool, state, depth_clip);
+   util_dump_member(stream, bool, state, clip_halfz);
     util_dump_member(stream, uint, state, clip_plane_enable);

     util_dump_member(stream, float, state, line_width);
diff --git a/src/gallium/docs/source/context.rst 
b/src/gallium/docs/source/context.rst
index 5861f46..5dfb5d9 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -78,7 +78,13 @@ objects. They all follow simple, one-method binding calls, 
e.g.
    and y would be [xmin..xmax-1] and [ymin..ymax-1]. The number of scissors
    should be the same as the number of set viewports and can be up to
    PIPE_MAX_VIEWPORTS.
-* ``set_viewport_states``
+  The scissor rectangle is specified in screen coordinates and is therefore
+  affected by the lower_left_origin state in the :ref:`Rasterizer`.
+* ``set_viewport_states`` specifies the conversion of clip coordinates to
+  screen coordinates.
+  Where the pixel corresponding to the screen coordinate origin (0, 0)
+  is stored in a resource depends on the lower_left_origin state in the
+  :ref:`Rasterizer`.


  Sampler Views
diff --git a/src/gallium/docs/source/cso/rasterizer.rst 
b/src/gallium/docs/source/cso/rasterizer.rst
index 8d473b8..81aab48 100644
--- a/src/gallium/docs/source/cso/rasterizer.rst
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -266,6 +266,16 @@ half_pixel_center
             |     |
         0.5 +-----+

+lower_left_origin:
+    When this is true, the screen coordinate origin (0, 0) is considered to be
+    the lower left corner.
+    This means that a pixel with screen-space coordinates (0, 0) will be stored
+    at the last line (y = height - 1) of the resource storage as far as
+    operations like blit and transfers are concerned.
+    Note that scissor state is specified in screen coordinates.
+    This setting is only legal if PIPE_CAP_RASTERIZER_LOWER_LEFT_ORIGIN is 
true.
+    If this is set, bottom_edge_rule must be set to true as well.
+
  bottom_edge_rule
      Determines what happens when a pixel sample lies precisely on a triangle
      edge.
@@ -274,15 +284,16 @@ bottom_edge_rule
      lies on the *bottom edge* or *left edge* (e.g., OpenGL drawables)::

          0                    x
-      0 +--------------------->
-        |
-        |  +-------------+
-        |  |             |
-        |  |             |
-        |  |             |
-        |  +=============+
-        |
-      y V
+      0 +--------------------->   y ^ (if lower_left_origin is true)
+        |                           |
+        |  +-------------+          | +=============+
+        |  |             |          | |             |
+        |  |             |          | |             |
+        |  |             |          | |             |
+        |  +=============+          | +-------------+
+        |                           |
+      y V                         0 +--------------------->
+                                    0                    x

      When false, a pixel sample is considered to lie inside of a triangle if it
      lies on the *top edge* or *left edge* (e.g., OpenGL FBOs, D3D)::
@@ -309,8 +320,13 @@ bottom_edge_rule

          Actually all graphics APIs use a top-left rasterization rule for pixel
          ownership, but their notion of top varies with the axis origin (which
-        can be either at y = 0 or at y = height).  Gallium instead always
-        assumes that top is always at y=0.
+        can be either at y = 0 or at y = height).
+
+        If PIPE_CAP_RASTERIZER_LOWER_LEFT_ORIGIN is advertised, this setting
+        must be set to true if lower_left_origin is true.
+        (This is because some hardware only supports switching the edge rule
+         implicitly by flipping the origin, while other hardware has a setting
+         for the edge rule but cannot flip the origin.)

      See also:
       - http://msdn.microsoft.com/en-us/library/windows/desktop/cc627092.aspx
diff --git a/src/gallium/docs/source/screen.rst 
b/src/gallium/docs/source/screen.rst
index ba34ec8..b48ab09 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -193,6 +193,8 @@ The integer capabilities:
  * ``PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT``: Whether
    PIPE_TRANSFER_PERSISTENT and PIPE_TRANSFER_COHERENT are supported
    for buffers.
+* ``PIPE_CAP_RASTERIZER_LOWER_LEFT_ORIGIN``: Indicates whether the setting of
+  lower_left_origin in pipe_rasterizer_state is supported.
  * ``PIPE_CAP_TEXTURE_QUERY_LOD``: Whether the ``LODQ`` instruction is
    supported.
  * ``PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET``: The minimum offset that can be used
diff --git a/src/gallium/include/pipe/p_defines.h 
b/src/gallium/include/pipe/p_defines.h
index d9b1547..5faed67 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -571,6 +571,7 @@ enum pipe_cap {
     PIPE_CAP_CONDITIONAL_RENDER_INVERTED = 108,
     PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE = 109,
     PIPE_CAP_SAMPLER_VIEW_TARGET = 110,
+   PIPE_CAP_RASTERIZER_LOWER_LEFT_ORIGIN = 111
  };

  #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
diff --git a/src/gallium/include/pipe/p_state.h 
b/src/gallium/include/pipe/p_state.h
index 36d253c..7b9996d 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -113,6 +113,7 @@ struct pipe_rasterizer_state
     unsigned flatshade_first:1;

     unsigned half_pixel_center:1;
+   unsigned lower_left_origin:1;
     unsigned bottom_edge_rule:1;

     /**
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c 
b/src/mesa/state_tracker/st_atom_rasterizer.c
index a228538..a56a883 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -232,8 +232,10 @@ static void update_raster_state( struct st_context *st )
                                    ctx->Color._ClampFragmentColor;

     raster->half_pixel_center = 1;
-   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
+   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
        raster->bottom_edge_rule = 1;
+      raster->lower_left_origin = st->use_rast_y_flip;
+   }

     /* ST_NEW_RASTERIZER */
     raster->rasterizer_discard = ctx->RasterDiscard;
diff --git a/src/mesa/state_tracker/st_atom_scissor.c 
b/src/mesa/state_tracker/st_atom_scissor.c
index b720309..b2ec41d 100644
--- a/src/mesa/state_tracker/st_atom_scissor.c
+++ b/src/mesa/state_tracker/st_atom_scissor.c
@@ -78,7 +78,7 @@ update_scissor( struct st_context *st )
        /* Now invert Y if needed.
         * Gallium drivers use the convention Y=0=top for surfaces.
         */
-      if (st_fb_orientation(fb) == Y_0_TOP) {
+      if (!st->use_rast_y_flip && st_fb_orientation(fb) == Y_0_TOP) {
           miny = fb->Height - scissor[i].maxy;
           maxy = fb->Height - scissor[i].miny;
           scissor[i].miny = miny;
diff --git a/src/mesa/state_tracker/st_atom_viewport.c 
b/src/mesa/state_tracker/st_atom_viewport.c
index 7584f9b..dd37ff1 100644
--- a/src/mesa/state_tracker/st_atom_viewport.c
+++ b/src/mesa/state_tracker/st_atom_viewport.c
@@ -46,7 +46,7 @@ update_viewport( struct st_context *st )
     int i;
     /* _NEW_BUFFERS
      */
-   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
+   if (!st->use_rast_y_flip && st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
        /* Drawing to a window.  The corresponding gallium surface uses
         * Y=0=TOP but OpenGL is Y=0=BOTTOM.  So we need to invert the viewport.
         */
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c 
b/src/mesa/state_tracker/st_cb_rasterpos.c
index 3707465..e825f96 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -143,7 +143,7 @@ rastpos_point(struct draw_stage *stage, struct prim_header 
*prim)
     /* update raster pos */
     pos = prim->v[0]->data[0];
     ctx->Current.RasterPos[0] = pos[0];
-   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
+   if (!st->use_rast_y_flip && st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
        ctx->Current.RasterPos[1] = height - pos[1]; /* invert Y */
     else
        ctx->Current.RasterPos[1] = pos[1];
diff --git a/src/mesa/state_tracker/st_context.c 
b/src/mesa/state_tracker/st_context.c
index 1723513..1858504 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -240,6 +240,9 @@ st_create_context_priv( struct gl_context *ctx, struct 
pipe_context *pipe,
     st->has_time_elapsed =
        screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED);

+   st->use_rast_y_flip =
+      screen->get_param(screen, PIPE_CAP_RASTERIZER_LOWER_LEFT_ORIGIN);
+
     /* GL limits and extensions */
     st_init_limits(st->pipe->screen, &ctx->Const, &ctx->Extensions);
     st_init_extensions(st->pipe->screen, &ctx->Const,
diff --git a/src/mesa/state_tracker/st_context.h 
b/src/mesa/state_tracker/st_context.h
index 58f14f9..857e448 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -91,6 +91,7 @@ struct st_context

     boolean needs_texcoord_semantic;
     boolean apply_texture_swizzle_to_border_color;
+   boolean use_rast_y_flip;

     /* On old libGL's for linux we need to invalidate the drawables
      * on glViewpport calls, this is set via a option.
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index a0da9f6..b18b6f0 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -4156,6 +4156,8 @@ struct st_translate {

     unsigned procType;  /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */

+   boolean fs_coord_y_flip; /* whether to apply STATE_FB_WPOS_Y_TRANSFORM */
+
     boolean error;
  };

@@ -4655,7 +4657,7 @@ emit_wpos_adjustment( struct st_translate *t,
                  wpos_input,
                  ureg_scalar(wpostrans, 0),
                  ureg_scalar(wpostrans, 1));
-   } else {
+   } else if (t->fs_coord_y_flip) {
        /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
         */
        ureg_MAD( ureg,
@@ -4743,7 +4745,7 @@ emit_wpos(struct st_context *st,
        /* Fragment shader wants pixel center integer */
        if (pscreen->get_param(pscreen, 
PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
           /* the driver supports pixel center integer */
-         adjY[1] = 1.0f;
+         adjY[1] = (float)t->fs_coord_y_flip;
           ureg_property_fs_coord_pixel_center(ureg, 
TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
        }
        else if (pscreen->get_param(pscreen, 
PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
@@ -4879,6 +4881,7 @@ st_translate_program(
     t->inputMapping = inputMapping;
     t->outputMapping = outputMapping;
     t->ureg = ureg;
+   t->fs_coord_y_flip = !st_context(ctx)->use_rast_y_flip;

     if (program->shader_program) {
        for (i = 0; i < program->shader_program->NumUserUniformStorage; i++) {
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c 
b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 26a5f51..5659c08 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -93,6 +93,8 @@ struct st_translate {

     unsigned procType;  /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */

+   boolean fs_coord_y_flip; /* whether to apply STATE_FB_WPOS_Y_TRANSFORM */
+
     boolean error;
  };

@@ -825,7 +827,7 @@ emit_wpos_adjustment( struct st_translate *t,
                  wpos_input,
                  ureg_scalar(wpostrans, 0),
                  ureg_scalar(wpostrans, 1));
-   } else {
+   } else if (t->fs_coord_y_flip) {
        /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
         */
        ureg_MAD( ureg,
@@ -913,7 +915,7 @@ emit_wpos(struct st_context *st,
        /* Fragment shader wants pixel center integer */
        if (pscreen->get_param(pscreen, 
PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
           /* the driver supports pixel center integer */
-         adjY[1] = 1.0f;
+         adjY[1] = (float)!t->fs_coord_y_flip;
           ureg_property_fs_coord_pixel_center(ureg, 
TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
        }
        else if (pscreen->get_param(pscreen, 
PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
@@ -1033,6 +1035,7 @@ st_translate_mesa_program(
     t->inputMapping = inputMapping;
     t->outputMapping = outputMapping;
     t->ureg = ureg;
+   t->fs_coord_y_flip = !st_context(ctx)->use_rast_y_flip;

     /*_mesa_print_program(program);*/



_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to