From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/auxiliary/util/u_blitter.c | 3 +- src/gallium/auxiliary/util/u_simple_shaders.c | 54 +++++++++++++++++++++++++-- src/gallium/auxiliary/util/u_simple_shaders.h | 3 +- src/mesa/state_tracker/st_cb_clear.c | 2 +- 4 files changed, 55 insertions(+), 7 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 7a3eb63..54d3009 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -358,21 +358,22 @@ static void bind_vs_passthrough(struct blitter_context_priv *ctx) } pipe->bind_vs_state(pipe, ctx->vs); } static void bind_vs_layered(struct blitter_context_priv *ctx) { struct pipe_context *pipe = ctx->base.pipe; if (!ctx->vs_layered) { - ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe); + ctx->vs_layered = + util_make_layered_clear_vertex_shader(pipe, true); } pipe->bind_vs_state(pipe, ctx->vs_layered); } static void bind_fs_empty(struct blitter_context_priv *ctx) { struct pipe_context *pipe = ctx->base.pipe; if (!ctx->fs_empty) { diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 9679545..763c634 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -72,65 +72,111 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, void * util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, uint num_attribs, const uint *semantic_names, const uint *semantic_indexes, bool window_space, bool layered, const struct pipe_stream_output_info *so) { struct ureg_program *ureg; uint i; + bool has_position = false; ureg = ureg_create( PIPE_SHADER_VERTEX ); if (!ureg) return NULL; if (window_space) ureg_property(ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE); for (i = 0; i < num_attribs; i++) { struct ureg_src src; struct ureg_dst dst; src = ureg_DECL_vs_input( ureg, i ); dst = ureg_DECL_output( ureg, semantic_names[i], semantic_indexes[i]); ureg_MOV( ureg, dst, src ); + + if (semantic_names[i] == TGSI_SEMANTIC_POSITION) + has_position = true; } if (layered) { struct ureg_src instance_id = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0); struct ureg_dst layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0); ureg_MOV(ureg, ureg_writemask(layer, TGSI_WRITEMASK_X), ureg_scalar(instance_id, TGSI_SWIZZLE_X)); } + /* If there is no position to pass from inputs, generate it from VertexID. + */ + if (!has_position) { + struct ureg_src vertex_id = + ureg_DECL_system_value(ureg, TGSI_SEMANTIC_VERTEXID, 0); + struct ureg_dst temp = ureg_DECL_temporary(ureg); + struct ureg_dst pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); + + vertex_id = ureg_scalar(vertex_id, TGSI_SWIZZLE_X); + + /* We want: + * VertexID posX posY + * 0 -1 -1 + * 1 1 -1 + * 2 1 1 + * 3 -1 1 + * + * posX = (VertexID >> 1) ^ (VertexID & 1) ? 1 : -1; + * posY = VertexID >> 1 ? 1 : -1; + * posZ = 0; + * posW = 1; + */ + ureg_USHR(ureg, ureg_writemask(temp, TGSI_WRITEMASK_Y), + vertex_id, ureg_imm1u(ureg, 1)); + ureg_AND(ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), + vertex_id, ureg_imm1u(ureg, 1)); + ureg_XOR(ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), + ureg_scalar(ureg_src(temp), TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp), TGSI_SWIZZLE_Y)); + + ureg_UCMP(ureg, ureg_writemask(pos, TGSI_WRITEMASK_XY), + ureg_swizzle(ureg_src(temp), + TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, + TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y), + ureg_imm1f(ureg, 1), ureg_imm1f(ureg, -1)); + ureg_MOV(ureg, ureg_writemask(pos, TGSI_WRITEMASK_ZW), + ureg_imm4f(ureg, 0, 0, 0, 1)); + } + ureg_END( ureg ); return ureg_create_shader_with_so_and_destroy( ureg, pipe, so ); } -void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe) +void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe, + bool has_position_input) { const unsigned semantic_names[] = {TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC}; const unsigned semantic_indices[] = {0, 0}; + unsigned offset = has_position_input ? 0 : 1; - return util_make_vertex_passthrough_shader_with_so(pipe, 2, semantic_names, - semantic_indices, false, - true, NULL); + return util_make_vertex_passthrough_shader_with_so(pipe, 2 - offset, + semantic_names + offset, + semantic_indices + offset, + false, true, NULL); } /** * Takes position and color, and outputs position, color, and instance id. */ void *util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe) { static const char text[] = "VERT\n" "DCL IN[0]\n" diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h index a281f57..bb2ad66 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.h +++ b/src/gallium/auxiliary/util/u_simple_shaders.h @@ -53,21 +53,22 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, extern void * util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, uint num_attribs, const uint *semantic_names, const uint *semantic_indexes, bool window_space, bool layered, const struct pipe_stream_output_info *so); extern void * -util_make_layered_clear_vertex_shader(struct pipe_context *pipe); +util_make_layered_clear_vertex_shader(struct pipe_context *pipe, + bool has_position_input); extern void * util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe); extern void * util_make_layered_clear_geometry_shader(struct pipe_context *pipe); extern void * util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, unsigned tex_target, diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index cda9c71..5afc876 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -148,21 +148,21 @@ set_vertex_shader_layered(struct st_context *st) if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID)) { assert(!"Got layered clear, but VS instancing is unsupported"); set_vertex_shader(st); return; } if (!st->clear.vs_layered) { bool vs_layer = pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT); if (vs_layer) { - st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe); + st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe, true); } else { st->clear.vs_layered = util_make_layered_clear_helper_vertex_shader(pipe); st->clear.gs_layered = util_make_layered_clear_geometry_shader(pipe); } } cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered); cso_set_geometry_shader_handle(st->cso_context, st->clear.gs_layered); } -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev