shader: Generate arrays only after the declarations are parsed.

When we enable indiviudal IO arrays that are passed from the host we
will no longer generate the one big array, but we know only after all
declarations have been parsed, whether the guest emitted these arrays or
whether we have indirect access to elements but no arrays so that we
need to build them. So do this array generation after parsing the
declarations.

v2: - If available use the output ranges size of the previous shader when
      defining the input range for the generated arrays, mesa might have
      optimized away some individual values.
    - Add a GLSL version requirement when an interface block will be created.

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org> (v1)
macos/master
Gert Wollny 6 years ago committed by Gert Wollny
parent e493907255
commit 08e7afd116
  1. 143
      src/vrend_shader.c

@ -761,7 +761,6 @@ 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;
bool indirect = false;
switch (decl->Declaration.File) { switch (decl->Declaration.File) {
case TGSI_FILE_INPUT: case TGSI_FILE_INPUT:
@ -772,7 +771,6 @@ iter_declaration(struct tgsi_iterate_context *iter,
return true; return true;
} }
i = ctx->num_inputs++; i = ctx->num_inputs++;
indirect = ctx_indirect_inputs(ctx);
if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) { if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
vrend_printf( "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs)); vrend_printf( "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
return false; return false;
@ -953,17 +951,6 @@ iter_declaration(struct tgsi_iterate_context *iter,
} }
/* fallthrough */ /* fallthrough */
case TGSI_SEMANTIC_PATCH: case TGSI_SEMANTIC_PATCH:
if (indirect && ctx->inputs[i].name == TGSI_SEMANTIC_PATCH) {
ctx->inputs[i].glsl_predefined_no_emit = true;
if (ctx->inputs[i].sid < ctx->patch_input_range.io.sid || ctx->patch_input_range.used == false) {
ctx->patch_input_range.io.sid = ctx->inputs[i].sid;
ctx->patch_input_range.io.first = i;
ctx->patch_input_range.used = true;
}
if (ctx->inputs[i].sid > ctx->patch_input_range.io.last)
ctx->patch_input_range.io.last = ctx->inputs[i].sid;
}
/* fallthrough */
case TGSI_SEMANTIC_GENERIC: case TGSI_SEMANTIC_GENERIC:
if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) { if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
if (ctx->key->coord_replace & (1 << ctx->inputs[i].sid)) { if (ctx->key->coord_replace & (1 << ctx->inputs[i].sid)) {
@ -976,16 +963,6 @@ iter_declaration(struct tgsi_iterate_context *iter,
break; break;
} }
} }
if (indirect && ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC) {
ctx->inputs[i].glsl_predefined_no_emit = true;
if (ctx->inputs[i].sid < ctx->generic_input_range.io.sid || ctx->generic_input_range.used == false) {
ctx->generic_input_range.io.sid = ctx->inputs[i].sid;
ctx->generic_input_range.io.first = i;
ctx->generic_input_range.used = true;
}
if (ctx->inputs[i].sid > ctx->generic_input_range.io.last)
ctx->generic_input_range.io.last = ctx->inputs[i].sid;
}
/* fallthrough */ /* fallthrough */
default: default:
name_prefix = get_stage_input_name_prefix(ctx, iter->processor.Processor); name_prefix = get_stage_input_name_prefix(ctx, iter->processor.Processor);
@ -1022,7 +999,6 @@ iter_declaration(struct tgsi_iterate_context *iter,
return true; return true;
} }
i = ctx->num_outputs++; i = ctx->num_outputs++;
indirect = ctx_indirect_outputs(ctx);
if (ctx->num_outputs > ARRAY_SIZE(ctx->outputs)) { if (ctx->num_outputs > ARRAY_SIZE(ctx->outputs)) {
vrend_printf( "Number of outputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->outputs)); vrend_printf( "Number of outputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->outputs));
return false; return false;
@ -1194,34 +1170,11 @@ iter_declaration(struct tgsi_iterate_context *iter,
break; break;
} }
/* fallthrough */ /* fallthrough */
case TGSI_SEMANTIC_PATCH:
case TGSI_SEMANTIC_GENERIC: case TGSI_SEMANTIC_GENERIC:
if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX)
if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC) if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC)
color_offset = -1; color_offset = -1;
if (indirect && ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC) {
ctx->outputs[i].glsl_predefined_no_emit = true;
require_glsl_ver(ctx, 150);
if (ctx->outputs[i].sid < ctx->generic_output_range.io.sid || ctx->generic_output_range.used == false) {
ctx->generic_output_range.io.first = i;
ctx->generic_output_range.io.sid = ctx->outputs[i].sid;
ctx->generic_output_range.used = true;
}
if (ctx->outputs[i].sid > ctx->generic_output_range.io.last)
ctx->generic_output_range.io.last = ctx->outputs[i].sid;
}
/* fallthrough */
case TGSI_SEMANTIC_PATCH:
if (indirect && ctx->outputs[i].name == TGSI_SEMANTIC_PATCH) {
ctx->outputs[i].glsl_predefined_no_emit = true;
require_glsl_ver(ctx, 150);
if (ctx->outputs[i].sid < ctx->patch_output_range.io.sid || ctx->patch_output_range.used == false) {
ctx->patch_output_range.io.first = i;
ctx->patch_output_range.io.sid = ctx->outputs[i].sid;
ctx->patch_output_range.used = true;
}
if (ctx->outputs[i].sid > ctx->patch_output_range.io.last)
ctx->patch_output_range.io.last = ctx->outputs[i].sid;
}
/* fallthrough */ /* fallthrough */
default: default:
name_prefix = get_stage_output_name_prefix(iter->processor.Processor); name_prefix = get_stage_output_name_prefix(iter->processor.Processor);
@ -3561,6 +3514,98 @@ get_source_info(struct dump_ctx *ctx,
return true; return true;
} }
/* We have indirect IO access, but the guest actually send separate values, so
* now we have to emulate an array.
*/
static
void rewrite_io_ranged(struct dump_ctx *ctx)
{
if ((ctx->info.indirect_files & (1 << TGSI_FILE_INPUT)) ||
ctx->key->num_indirect_generic_inputs ||
ctx->key->num_indirect_patch_inputs) {
for (uint i = 0; i < ctx->num_inputs; ++i) {
if (ctx->inputs[i].name == TGSI_SEMANTIC_PATCH) {
ctx->inputs[i].glsl_predefined_no_emit = true;
if (ctx->inputs[i].sid < ctx->patch_input_range.io.sid || ctx->patch_input_range.used == false) {
ctx->patch_input_range.io.first = i;
ctx->patch_input_range.io.name = TGSI_SEMANTIC_PATCH;
ctx->patch_input_range.io.sid = ctx->inputs[i].sid;
ctx->patch_input_range.used = true;
}
if (ctx->inputs[i].sid > ctx->patch_input_range.io.last)
ctx->patch_input_range.io.last = ctx->inputs[i].sid;
}
if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC) {
ctx->inputs[i].glsl_predefined_no_emit = true;
if (ctx->inputs[i].sid < ctx->generic_input_range.io.sid || ctx->generic_input_range.used == false) {
ctx->generic_input_range.io.sid = ctx->inputs[i].sid;
ctx->generic_input_range.io.first = i;
ctx->generic_input_range.io.name = TGSI_SEMANTIC_GENERIC;
ctx->generic_input_range.used = true;
}
if (ctx->inputs[i].sid > ctx->generic_input_range.io.last)
ctx->generic_input_range.io.last = ctx->inputs[i].sid;
}
if (ctx->key->num_indirect_generic_inputs > 0)
ctx->generic_input_range.io.last = ctx->generic_input_range.io.sid + ctx->key->num_indirect_generic_inputs - 1;
if (ctx->key->num_indirect_patch_inputs > 0)
ctx->patch_input_range.io.last = ctx->patch_input_range.io.sid + ctx->key->num_indirect_patch_inputs - 1;
}
snprintf(ctx->patch_input_range.io.glsl_name, 64, "%s_p%d",
get_stage_input_name_prefix(ctx, ctx->prog_type), ctx->patch_input_range.io.sid);
snprintf(ctx->generic_input_range.io.glsl_name, 64, "%s_g%d",
get_stage_input_name_prefix(ctx, ctx->prog_type), ctx->generic_input_range.io.sid);
if (prefer_generic_io_block(ctx, io_in))
require_glsl_ver(ctx, 150);
}
if ((ctx->info.indirect_files & (1 << TGSI_FILE_OUTPUT)) ||
ctx->key->num_indirect_generic_outputs ||
ctx->key->num_indirect_patch_outputs) {
for (uint i = 0; i < ctx->num_outputs; ++i) {
if (ctx->outputs[i].name == TGSI_SEMANTIC_PATCH) {
ctx->outputs[i].glsl_predefined_no_emit = true;
if (ctx->outputs[i].sid < ctx->patch_output_range.io.sid || ctx->patch_output_range.used == false) {
ctx->patch_output_range.io.first = i;
ctx->patch_output_range.io.name = TGSI_SEMANTIC_PATCH;
ctx->patch_output_range.io.sid = ctx->outputs[i].sid;
ctx->patch_output_range.used = true;
}
if (ctx->outputs[i].sid > ctx->patch_output_range.io.last) {
ctx->patch_output_range.io.last = ctx->outputs[i].sid;
}
}
if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC) {
ctx->outputs[i].glsl_predefined_no_emit = true;
if (ctx->outputs[i].sid < ctx->generic_output_range.io.sid || ctx->generic_output_range.used == false) {
ctx->generic_output_range.io.sid = ctx->outputs[i].sid;
ctx->generic_output_range.io.first = i;
ctx->generic_output_range.io.name = TGSI_SEMANTIC_GENERIC;
ctx->generic_output_range.used = true;
}
if (ctx->outputs[i].sid > ctx->generic_output_range.io.last) {
ctx->generic_output_range.io.last = ctx->outputs[i].sid;
}
}
}
snprintf(ctx->patch_output_range.io.glsl_name, 64, "%s_p%d",
get_stage_output_name_prefix(ctx->prog_type), ctx->patch_output_range.io.sid);
snprintf(ctx->generic_output_range.io.glsl_name, 64, "%s_g%d",
get_stage_output_name_prefix(ctx->prog_type), ctx->generic_output_range.io.sid);
if (prefer_generic_io_block(ctx, io_out))
require_glsl_ver(ctx, 150);
}
}
static boolean static boolean
iter_instruction(struct tgsi_iterate_context *iter, iter_instruction(struct tgsi_iterate_context *iter,
struct tgsi_full_instruction *inst) struct tgsi_full_instruction *inst)
@ -3580,6 +3625,8 @@ iter_instruction(struct tgsi_iterate_context *iter,
ctx->prog_type = iter->processor.Processor; ctx->prog_type = iter->processor.Processor;
if (instno == 0) { if (instno == 0) {
rewrite_io_ranged(ctx);
emit_buf(ctx, "void main(void)\n{\n"); emit_buf(ctx, "void main(void)\n{\n");
if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) { if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
emit_color_select(ctx); emit_color_select(ctx);

Loading…
Cancel
Save