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);*/ -- 2.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev