[Mesa-dev] [PATCH 02/14] mesa/gallium: API settings / rasterization rules
Brian Paul
brianp at vmware.com
Mon Oct 20 08:37:30 PDT 2014
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 <e0425955 at student.tuwien.ac.at>
>
> D3D9 has different system coordinate, add neccessary infrastructure for it.
>
> Signed-off-by: David Heidelberger <david.heidelberger at 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);*/
>
>
More information about the mesa-dev
mailing list