shader: Pass information about the layout of generics and patches to the next stage

mesa optimizes away the information about input layouts for generics and
patches for TCS, TES, and GEOM shaders (all that pass these inputs as
arrays), but when input arrays are allowed, then these varyings may
actually have overlapping layouts (at least some piglits do, even though
they don't specifically require ARB_enhanced_layouts).

To be able to link shaders like these with enables arrays pass this info
to the next stage.

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-By: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Gert Wollny 6 years ago committed by Gert Wollny
parent 4efe5c1ce2
commit 956a6ceb8d
  1. 2
      src/virgl_hw.h
  2. 17
      src/vrend_renderer.c
  3. 28
      src/vrend_shader.c
  4. 15
      src/vrend_shader.h

@ -389,8 +389,8 @@ enum virgl_ctx_errors {
VIRGL_ERROR_CTX_ILLEGAL_SURFACE, VIRGL_ERROR_CTX_ILLEGAL_SURFACE,
VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT, VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT,
VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER,
VIRGL_ERROR_CTX_GLES_HAVE_TES_BUT_MISS_TCS,
}; };
#define VIRGL_RESOURCE_Y_0_TOP (1 << 0) #define VIRGL_RESOURCE_Y_0_TOP (1 << 0)
#endif #endif

@ -679,7 +679,9 @@ static inline const char *pipe_shader_to_prefix(int shader_type)
}; };
} }
static const char *vrend_ctx_error_strings[] = { "None", "Unknown", "Illegal shader", "Illegal handle", "Illegal resource", "Illegal surface", "Illegal vertex format", "Illegal command buffer" }; static const char *vrend_ctx_error_strings[] = { "None", "Unknown", "Illegal shader", "Illegal handle", "Illegal resource",
"Illegal surface", "Illegal vertex format", "Illegal command buffer",
"On GLES context and shader program has tesselation evaluation shader but no tesselation control shader"};
static void __report_context_error(const char *fname, struct vrend_context *ctx, enum virgl_ctx_errors error, uint32_t value) static void __report_context_error(const char *fname, struct vrend_context *ctx, enum virgl_ctx_errors error, uint32_t value)
{ {
@ -2913,7 +2915,7 @@ static inline void vrend_fill_shader_key(struct vrend_context *ctx,
if (!ctx->shader_cfg.use_gles) if (!ctx->shader_cfg.use_gles)
prev_type = PIPE_SHADER_VERTEX; prev_type = PIPE_SHADER_VERTEX;
else else
vrend_printf("Error OpenGL ES doesn't allow a tesselation evaluation shader without a teselation control shader"); report_context_error(ctx, VIRGL_ERROR_CTX_GLES_HAVE_TES_BUT_MISS_TCS, 0);
break; break;
case PIPE_SHADER_TESS_CTRL: case PIPE_SHADER_TESS_CTRL:
prev_type = PIPE_SHADER_VERTEX; prev_type = PIPE_SHADER_VERTEX;
@ -2927,6 +2929,12 @@ static inline void vrend_fill_shader_key(struct vrend_context *ctx,
key->prev_stage_num_cull_out = ctx->sub->shaders[prev_type]->sinfo.num_cull_out; key->prev_stage_num_cull_out = ctx->sub->shaders[prev_type]->sinfo.num_cull_out;
key->num_indirect_generic_inputs = ctx->sub->shaders[prev_type]->sinfo.num_indirect_generic_outputs; key->num_indirect_generic_inputs = ctx->sub->shaders[prev_type]->sinfo.num_indirect_generic_outputs;
key->num_indirect_patch_inputs = ctx->sub->shaders[prev_type]->sinfo.num_indirect_patch_outputs; key->num_indirect_patch_inputs = ctx->sub->shaders[prev_type]->sinfo.num_indirect_patch_outputs;
key->num_prev_generic_and_patch_outputs = ctx->sub->shaders[prev_type]->sinfo.num_generic_and_patch_outputs;
key->guest_sent_io_arrays = ctx->sub->shaders[prev_type]->sinfo.guest_sent_io_arrays;
memcpy(key->prev_stage_generic_and_patch_outputs_layout,
ctx->sub->shaders[prev_type]->sinfo.generic_outputs_layout,
64 * sizeof (struct vrend_layout_info));
} }
int next_type = -1; int next_type = -1;
@ -2936,7 +2944,12 @@ static inline void vrend_fill_shader_key(struct vrend_context *ctx,
next_type = PIPE_SHADER_TESS_CTRL; next_type = PIPE_SHADER_TESS_CTRL;
else if (key->gs_present) else if (key->gs_present)
next_type = PIPE_SHADER_GEOMETRY; next_type = PIPE_SHADER_GEOMETRY;
else if (key->tes_present) {
if (!ctx->shader_cfg.use_gles)
next_type = PIPE_SHADER_TESS_EVAL;
else else
report_context_error(ctx, VIRGL_ERROR_CTX_GLES_HAVE_TES_BUT_MISS_TCS, 0);
} else
next_type = PIPE_SHADER_FRAGMENT; next_type = PIPE_SHADER_FRAGMENT;
break; break;
case PIPE_SHADER_TESS_CTRL: case PIPE_SHADER_TESS_CTRL:

@ -779,6 +779,7 @@ iter_declaration(struct tgsi_iterate_context *iter,
int color_offset = 0; int color_offset = 0;
const char *name_prefix = ""; const char *name_prefix = "";
bool add_two_side = false; bool add_two_side = false;
unsigned mask_temp;
switch (decl->Declaration.File) { switch (decl->Declaration.File) {
case TGSI_FILE_INPUT: case TGSI_FILE_INPUT:
@ -1015,7 +1016,7 @@ iter_declaration(struct tgsi_iterate_context *iter,
ctx->inputs[i].swizzle_offset = 0; ctx->inputs[i].swizzle_offset = 0;
ctx->inputs[i].override_no_wm = false; ctx->inputs[i].override_no_wm = false;
snprintf(ctx->inputs[i].glsl_name, 64, "%s_f%d", name_prefix, ctx->inputs[i].sid); snprintf(ctx->inputs[i].glsl_name, 64, "%s_f%d", name_prefix, ctx->inputs[i].sid);
else if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR) } else if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR)
snprintf(ctx->inputs[i].glsl_name, 64, "%s_c%d", name_prefix, ctx->inputs[i].sid); snprintf(ctx->inputs[i].glsl_name, 64, "%s_c%d", name_prefix, ctx->inputs[i].sid);
else if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC) else if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC)
snprintf(ctx->inputs[i].glsl_name, 64, "%s_g%d", name_prefix, ctx->inputs[i].sid); snprintf(ctx->inputs[i].glsl_name, 64, "%s_g%d", name_prefix, ctx->inputs[i].sid);
@ -1243,7 +1244,7 @@ iter_declaration(struct tgsi_iterate_context *iter,
ctx->outputs[i].swizzle_offset = 0; ctx->outputs[i].swizzle_offset = 0;
ctx->outputs[i].override_no_wm = false; ctx->outputs[i].override_no_wm = false;
snprintf(ctx->outputs[i].glsl_name, 64, "%s_f%d", name_prefix, ctx->outputs[i].sid); snprintf(ctx->outputs[i].glsl_name, 64, "%s_f%d", name_prefix, ctx->outputs[i].sid);
else if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR) } else if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR)
snprintf(ctx->outputs[i].glsl_name, 64, "%s_c%d", name_prefix, ctx->outputs[i].sid); snprintf(ctx->outputs[i].glsl_name, 64, "%s_c%d", name_prefix, ctx->outputs[i].sid);
else if (ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR) else if (ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR)
snprintf(ctx->outputs[i].glsl_name, 64, "%s_bc%d", name_prefix, ctx->outputs[i].sid); snprintf(ctx->outputs[i].glsl_name, 64, "%s_bc%d", name_prefix, ctx->outputs[i].sid);
@ -1714,7 +1715,7 @@ static void emit_so_movs(struct dump_ctx *ctx)
ctx->has_clipvertex_so = true; ctx->has_clipvertex_so = true;
} else { } else {
char out_var[255]; char out_var[255];
get_so_name(ctx->cfg->use_gles, output, ctx->so->output[i].register_index, out_var, "block_", stage_prefix); get_so_name(ctx, true, output, ctx->so->output[i].register_index, out_var, writemask);
ctx->so_names[i] = strdup(out_var); ctx->so_names[i] = strdup(out_var);
} }
} else { } else {
@ -1744,7 +1745,7 @@ static void emit_so_movs(struct dump_ctx *ctx)
} else { } else {
if (ctx->write_so_outputs[i]) { if (ctx->write_so_outputs[i]) {
char out_var[255]; char out_var[255];
get_so_name(ctx->cfg->use_gles, output, ctx->so->output[i].register_index, out_var, "", stage_prefix); get_so_name(ctx, false, output, ctx->so->output[i].register_index, out_var, writemask);
emit_buff(ctx, "tfout%d = %s(%s%s);\n", i, outtype, out_var, writemask); emit_buff(ctx, "tfout%d = %s(%s%s);\n", i, outtype, out_var, writemask);
} }
} }
@ -5538,6 +5539,8 @@ bool vrend_convert_shader(struct vrend_context *rctx,
ctx.ssbo_atomic_array_base = 0xffffffff; ctx.ssbo_atomic_array_base = 0xffffffff;
ctx.has_sample_input = false; ctx.has_sample_input = false;
ctx.req_local_mem = req_local_mem; ctx.req_local_mem = req_local_mem;
ctx.guest_sent_io_arrays = key->guest_sent_io_arrays;
tgsi_scan_shader(tokens, &ctx.info); tgsi_scan_shader(tokens, &ctx.info);
/* if we are in core profile mode we should use GLSL 1.40 */ /* if we are in core profile mode we should use GLSL 1.40 */
if (cfg->use_core_profile && cfg->glsl_version >= 140) if (cfg->use_core_profile && cfg->glsl_version >= 140)
@ -5631,6 +5634,23 @@ bool vrend_convert_shader(struct vrend_context *rctx,
} }
} }
/* Record information about the layout of generics and patches for apssing it
* to the next shader stage. mesa/tgsi doesn't provide this information for
* TCS, TES, and GEOM shaders.
*/
sinfo->guest_sent_io_arrays = ctx.guest_sent_io_arrays;
sinfo->num_generic_and_patch_outputs = 0;
for(unsigned i = 0; i < ctx.num_outputs; i++) {
sinfo->generic_outputs_layout[sinfo->num_generic_and_patch_outputs].name = ctx.outputs[i].name;
sinfo->generic_outputs_layout[sinfo->num_generic_and_patch_outputs].sid = ctx.outputs[i].sid;
sinfo->generic_outputs_layout[sinfo->num_generic_and_patch_outputs].location = ctx.outputs[i].layout_location;
sinfo->generic_outputs_layout[sinfo->num_generic_and_patch_outputs].array_id = ctx.outputs[i].array_id;
sinfo->generic_outputs_layout[sinfo->num_generic_and_patch_outputs].usage_mask = ctx.outputs[i].usage_mask;
if (ctx.outputs[i].name == TGSI_SEMANTIC_GENERIC || ctx.outputs[i].name == TGSI_SEMANTIC_PATCH) {
sinfo->num_generic_and_patch_outputs++;
}
}
sinfo->so_names = ctx.so_names; sinfo->so_names = ctx.so_names;
sinfo->attrib_input_mask = ctx.attrib_input_mask; sinfo->attrib_input_mask = ctx.attrib_input_mask;
if (sinfo->sampler_arrays) if (sinfo->sampler_arrays)

@ -42,11 +42,22 @@ struct vrend_array {
int array_size; int array_size;
}; };
struct vrend_layout_info {
unsigned name;
int sid;
int location;
int array_id;
int usage_mask;
};
struct vrend_shader_info { struct vrend_shader_info {
uint32_t samplers_used_mask; uint32_t samplers_used_mask;
uint32_t images_used_mask; uint32_t images_used_mask;
uint32_t ubo_used_mask; uint32_t ubo_used_mask;
uint32_t ssbo_used_mask; uint32_t ssbo_used_mask;
uint32_t num_generic_and_patch_outputs;
bool guest_sent_io_arrays;
struct vrend_layout_info generic_outputs_layout[64];
int num_consts; int num_consts;
int num_inputs; int num_inputs;
int num_interps; int num_interps;
@ -94,6 +105,10 @@ struct vrend_shader_key {
bool tes_present; bool tes_present;
bool flatshade; bool flatshade;
bool prev_stage_pervertex_out; bool prev_stage_pervertex_out;
bool guest_sent_io_arrays;
uint32_t num_prev_generic_and_patch_outputs;
struct vrend_layout_info prev_stage_generic_and_patch_outputs_layout[64];
uint8_t prev_stage_num_clip_out; uint8_t prev_stage_num_clip_out;
uint8_t prev_stage_num_cull_out; uint8_t prev_stage_num_cull_out;
float alpha_ref_val; float alpha_ref_val;

Loading…
Cancel
Save