st/mesa: add a fallback for clear_with_quad when no vs_layer
Not all drivers can set gl_Layer from VS. Add a fallback that passes the instance id from VS to GS, and then uses the GS to set the layer. Tested by adding quad_buffers |= clear_buffers; clear_buffers = 0; to the st_Clear logic, and forcing set_vertex_shader_layered in all cases. No piglit regressions (on piglits with 'clear' in the name). Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Cc: "10.4 10.3" <mesa-stable@lists.freedesktop.org>
This commit is contained in:
parent
7b8e04b3f0
commit
68db29c434
|
@ -130,6 +130,76 @@ void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe)
|
|||
return pipe->create_vs_state(pipe, &state);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"
|
||||
"DCL IN[1]\n"
|
||||
"DCL SV[0], INSTANCEID\n"
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL OUT[1], GENERIC[0]\n"
|
||||
"DCL OUT[2], GENERIC[1]\n"
|
||||
|
||||
"MOV OUT[0], IN[0]\n"
|
||||
"MOV OUT[1], IN[1]\n"
|
||||
"MOV OUT[2].x, SV[0].xxxx\n"
|
||||
"END\n";
|
||||
struct tgsi_token tokens[1000];
|
||||
struct pipe_shader_state state = {tokens};
|
||||
|
||||
if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
return pipe->create_vs_state(pipe, &state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes position, color, and target layer, and emits vertices on that target
|
||||
* layer, with the specified color.
|
||||
*/
|
||||
void *util_make_layered_clear_geometry_shader(struct pipe_context *pipe)
|
||||
{
|
||||
static const char text[] =
|
||||
"GEOM\n"
|
||||
"PROPERTY GS_INPUT_PRIMITIVE TRIANGLES\n"
|
||||
"PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP\n"
|
||||
"PROPERTY GS_MAX_OUTPUT_VERTICES 3\n"
|
||||
"PROPERTY GS_INVOCATIONS 1\n"
|
||||
"DCL IN[][0], POSITION\n" /* position */
|
||||
"DCL IN[][1], GENERIC[0]\n" /* color */
|
||||
"DCL IN[][2], GENERIC[1]\n" /* vs invocation */
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL OUT[1], GENERIC[0]\n"
|
||||
"DCL OUT[2], LAYER\n"
|
||||
"IMM[0] INT32 {0, 0, 0, 0}\n"
|
||||
|
||||
"MOV OUT[0], IN[0][0]\n"
|
||||
"MOV OUT[1], IN[0][1]\n"
|
||||
"MOV OUT[2].x, IN[0][2].xxxx\n"
|
||||
"EMIT IMM[0].xxxx\n"
|
||||
"MOV OUT[0], IN[1][0]\n"
|
||||
"MOV OUT[1], IN[1][1]\n"
|
||||
"MOV OUT[2].x, IN[1][2].xxxx\n"
|
||||
"EMIT IMM[0].xxxx\n"
|
||||
"MOV OUT[0], IN[2][0]\n"
|
||||
"MOV OUT[1], IN[2][1]\n"
|
||||
"MOV OUT[2].x, IN[2][2].xxxx\n"
|
||||
"EMIT IMM[0].xxxx\n"
|
||||
"END\n";
|
||||
struct tgsi_token tokens[1000];
|
||||
struct pipe_shader_state state = {tokens};
|
||||
|
||||
if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
return pipe->create_gs_state(pipe, &state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make simple fragment texture shader:
|
||||
|
|
|
@ -61,6 +61,12 @@ util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe,
|
|||
extern void *
|
||||
util_make_layered_clear_vertex_shader(struct pipe_context *pipe);
|
||||
|
||||
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,
|
||||
|
|
|
@ -88,6 +88,14 @@ st_destroy_clear(struct st_context *st)
|
|||
cso_delete_vertex_shader(st->cso_context, st->clear.vs);
|
||||
st->clear.vs = NULL;
|
||||
}
|
||||
if (st->clear.vs_layered) {
|
||||
cso_delete_vertex_shader(st->cso_context, st->clear.vs_layered);
|
||||
st->clear.vs_layered = NULL;
|
||||
}
|
||||
if (st->clear.gs_layered) {
|
||||
cso_delete_geometry_shader(st->cso_context, st->clear.gs_layered);
|
||||
st->clear.gs_layered = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,6 +136,7 @@ set_vertex_shader(struct st_context *st)
|
|||
}
|
||||
|
||||
cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
|
||||
cso_set_geometry_shader_handle(st->cso_context, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,18 +145,25 @@ set_vertex_shader_layered(struct st_context *st)
|
|||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
|
||||
if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) ||
|
||||
!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) {
|
||||
assert(!"Got layered clear, but the VS layer output is unsupported");
|
||||
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) {
|
||||
st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe);
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -331,7 +347,6 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
|
|||
}
|
||||
|
||||
set_fragment_shader(st);
|
||||
cso_set_geometry_shader_handle(st->cso_context, NULL);
|
||||
|
||||
if (num_layers > 1)
|
||||
set_vertex_shader_layered(st);
|
||||
|
|
|
@ -181,6 +181,7 @@ struct st_context
|
|||
void *vs;
|
||||
void *fs;
|
||||
void *vs_layered;
|
||||
void *gs_layered;
|
||||
} clear;
|
||||
|
||||
/** used for anything using util_draw_vertex_buffer */
|
||||
|
|
Loading…
Reference in New Issue