|
|
@@ -987,7 +987,9 @@ remove_unused_shader_inputs_and_outputs(bool is_separate_shader_object,
|
|
|
|
* will fail to find any matching variable.
|
|
|
|
* will fail to find any matching variable.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
void
|
|
|
|
tfeedback_decl::init(struct gl_context *ctx, const void *mem_ctx,
|
|
|
|
tfeedback_decl::init(const struct gl_constants *consts,
|
|
|
|
|
|
|
|
const struct gl_extensions *exts,
|
|
|
|
|
|
|
|
const void *mem_ctx,
|
|
|
|
const char *input)
|
|
|
|
const char *input)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* We don't have to be pedantic about what is a valid GLSL variable name,
|
|
|
|
/* We don't have to be pedantic about what is a valid GLSL variable name,
|
|
|
@@ -1004,7 +1006,7 @@ tfeedback_decl::init(struct gl_context *ctx, const void *mem_ctx,
|
|
|
|
this->buffer = 0;
|
|
|
|
this->buffer = 0;
|
|
|
|
this->offset = 0;
|
|
|
|
this->offset = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (ctx->Extensions.ARB_transform_feedback3) {
|
|
|
|
if (exts->ARB_transform_feedback3) {
|
|
|
|
/* Parse gl_NextBuffer. */
|
|
|
|
/* Parse gl_NextBuffer. */
|
|
|
|
if (strcmp(input, "gl_NextBuffer") == 0) {
|
|
|
|
if (strcmp(input, "gl_NextBuffer") == 0) {
|
|
|
|
this->next_buffer_separator = true;
|
|
|
|
this->next_buffer_separator = true;
|
|
|
@@ -1046,19 +1048,19 @@ tfeedback_decl::init(struct gl_context *ctx, const void *mem_ctx,
|
|
|
|
* class must behave specially to account for the fact that gl_ClipDistance
|
|
|
|
* class must behave specially to account for the fact that gl_ClipDistance
|
|
|
|
* is converted from a float[8] to a vec4[2].
|
|
|
|
* is converted from a float[8] to a vec4[2].
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].LowerCombinedClipCullDistance &&
|
|
|
|
if (consts->ShaderCompilerOptions[MESA_SHADER_VERTEX].LowerCombinedClipCullDistance &&
|
|
|
|
strcmp(this->var_name, "gl_ClipDistance") == 0) {
|
|
|
|
strcmp(this->var_name, "gl_ClipDistance") == 0) {
|
|
|
|
this->lowered_builtin_array_variable = clip_distance;
|
|
|
|
this->lowered_builtin_array_variable = clip_distance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].LowerCombinedClipCullDistance &&
|
|
|
|
if (consts->ShaderCompilerOptions[MESA_SHADER_VERTEX].LowerCombinedClipCullDistance &&
|
|
|
|
strcmp(this->var_name, "gl_CullDistance") == 0) {
|
|
|
|
strcmp(this->var_name, "gl_CullDistance") == 0) {
|
|
|
|
this->lowered_builtin_array_variable = cull_distance;
|
|
|
|
this->lowered_builtin_array_variable = cull_distance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ctx->Const.LowerTessLevel &&
|
|
|
|
if (consts->LowerTessLevel &&
|
|
|
|
(strcmp(this->var_name, "gl_TessLevelOuter") == 0))
|
|
|
|
(strcmp(this->var_name, "gl_TessLevelOuter") == 0))
|
|
|
|
this->lowered_builtin_array_variable = tess_level_outer;
|
|
|
|
this->lowered_builtin_array_variable = tess_level_outer;
|
|
|
|
if (ctx->Const.LowerTessLevel &&
|
|
|
|
if (consts->LowerTessLevel &&
|
|
|
|
(strcmp(this->var_name, "gl_TessLevelInner") == 0))
|
|
|
|
(strcmp(this->var_name, "gl_TessLevelInner") == 0))
|
|
|
|
this->lowered_builtin_array_variable = tess_level_inner;
|
|
|
|
this->lowered_builtin_array_variable = tess_level_inner;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1091,7 +1093,7 @@ tfeedback_decl::is_same(const tfeedback_decl &x, const tfeedback_decl &y)
|
|
|
|
* is returned.
|
|
|
|
* is returned.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
tfeedback_decl::assign_location(struct gl_context *ctx,
|
|
|
|
tfeedback_decl::assign_location(const struct gl_constants *consts,
|
|
|
|
struct gl_shader_program *prog)
|
|
|
|
struct gl_shader_program *prog)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
assert(this->is_varying());
|
|
|
|
assert(this->is_varying());
|
|
|
@@ -1179,7 +1181,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS &&
|
|
|
|
if (prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS &&
|
|
|
|
this->num_components() >
|
|
|
|
this->num_components() >
|
|
|
|
ctx->Const.MaxTransformFeedbackSeparateComponents) {
|
|
|
|
consts->MaxTransformFeedbackSeparateComponents) {
|
|
|
|
linker_error(prog, "Transform feedback varying %s exceeds "
|
|
|
|
linker_error(prog, "Transform feedback varying %s exceeds "
|
|
|
|
"MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS.",
|
|
|
|
"MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS.",
|
|
|
|
this->orig_name);
|
|
|
|
this->orig_name);
|
|
|
@@ -1225,7 +1227,8 @@ tfeedback_decl::get_num_outputs() const
|
|
|
|
* is returned.
|
|
|
|
* is returned.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
tfeedback_decl::store(const struct gl_constants *consts,
|
|
|
|
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
struct gl_transform_feedback_info *info,
|
|
|
|
struct gl_transform_feedback_info *info,
|
|
|
|
unsigned buffer, unsigned buffer_index,
|
|
|
|
unsigned buffer, unsigned buffer_index,
|
|
|
|
const unsigned max_outputs,
|
|
|
|
const unsigned max_outputs,
|
|
|
@@ -1276,7 +1279,7 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
if ((prog->TransformFeedback.BufferMode == GL_INTERLEAVED_ATTRIBS ||
|
|
|
|
if ((prog->TransformFeedback.BufferMode == GL_INTERLEAVED_ATTRIBS ||
|
|
|
|
has_xfb_qualifiers) &&
|
|
|
|
has_xfb_qualifiers) &&
|
|
|
|
xfb_offset + num_components >
|
|
|
|
xfb_offset + num_components >
|
|
|
|
ctx->Const.MaxTransformFeedbackInterleavedComponents) {
|
|
|
|
consts->MaxTransformFeedbackInterleavedComponents) {
|
|
|
|
linker_error(prog,
|
|
|
|
linker_error(prog,
|
|
|
|
"The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
|
|
|
|
"The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
|
|
|
|
"limit has been exceeded.");
|
|
|
|
"limit has been exceeded.");
|
|
|
@@ -1291,7 +1294,7 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
* feedback offsets."
|
|
|
|
* feedback offsets."
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
const unsigned max_components =
|
|
|
|
const unsigned max_components =
|
|
|
|
ctx->Const.MaxTransformFeedbackInterleavedComponents;
|
|
|
|
consts->MaxTransformFeedbackInterleavedComponents;
|
|
|
|
const unsigned first_component = xfb_offset;
|
|
|
|
const unsigned first_component = xfb_offset;
|
|
|
|
const unsigned last_component = xfb_offset + num_components - 1;
|
|
|
|
const unsigned last_component = xfb_offset + num_components - 1;
|
|
|
|
const unsigned start_word = BITSET_BITWORD(first_component);
|
|
|
|
const unsigned start_word = BITSET_BITWORD(first_component);
|
|
|
@@ -1503,12 +1506,14 @@ tfeedback_decl::set_lowered_candidate(const tfeedback_candidate *candidate)
|
|
|
|
* is returned.
|
|
|
|
* is returned.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
static bool
|
|
|
|
parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
parse_tfeedback_decls(const struct gl_constants *consts,
|
|
|
|
|
|
|
|
const struct gl_extensions *exts,
|
|
|
|
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
const void *mem_ctx, unsigned num_names,
|
|
|
|
const void *mem_ctx, unsigned num_names,
|
|
|
|
char **varying_names, tfeedback_decl *decls)
|
|
|
|
char **varying_names, tfeedback_decl *decls)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (unsigned i = 0; i < num_names; ++i) {
|
|
|
|
for (unsigned i = 0; i < num_names; ++i) {
|
|
|
|
decls[i].init(ctx, mem_ctx, varying_names[i]);
|
|
|
|
decls[i].init(consts, exts, mem_ctx, varying_names[i]);
|
|
|
|
|
|
|
|
|
|
|
|
if (!decls[i].is_varying())
|
|
|
|
if (!decls[i].is_varying())
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
@@ -1557,7 +1562,8 @@ cmp_xfb_offset(const void * x_generic, const void * y_generic)
|
|
|
|
* is returned.
|
|
|
|
* is returned.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
static bool
|
|
|
|
store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
store_tfeedback_info(const struct gl_constants *consts,
|
|
|
|
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
unsigned num_tfeedback_decls,
|
|
|
|
unsigned num_tfeedback_decls,
|
|
|
|
tfeedback_decl *tfeedback_decls, bool has_xfb_qualifiers,
|
|
|
|
tfeedback_decl *tfeedback_decls, bool has_xfb_qualifiers,
|
|
|
|
const void *mem_ctx)
|
|
|
|
const void *mem_ctx)
|
|
|
@@ -1568,7 +1574,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
/* Make sure MaxTransformFeedbackBuffers is less than 32 so the bitmask for
|
|
|
|
/* Make sure MaxTransformFeedbackBuffers is less than 32 so the bitmask for
|
|
|
|
* tracking the number of buffers doesn't overflow.
|
|
|
|
* tracking the number of buffers doesn't overflow.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
assert(ctx->Const.MaxTransformFeedbackBuffers < 32);
|
|
|
|
assert(consts->MaxTransformFeedbackBuffers < 32);
|
|
|
|
|
|
|
|
|
|
|
|
bool separate_attribs_mode =
|
|
|
|
bool separate_attribs_mode =
|
|
|
|
prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
|
|
|
|
prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
|
|
|
@@ -1607,7 +1613,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
if (!has_xfb_qualifiers && separate_attribs_mode) {
|
|
|
|
if (!has_xfb_qualifiers && separate_attribs_mode) {
|
|
|
|
/* GL_SEPARATE_ATTRIBS */
|
|
|
|
/* GL_SEPARATE_ATTRIBS */
|
|
|
|
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
|
|
|
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
|
|
|
if (!tfeedback_decls[i].store(ctx, prog,
|
|
|
|
if (!tfeedback_decls[i].store(consts, prog,
|
|
|
|
xfb_prog->sh.LinkedTransformFeedback,
|
|
|
|
xfb_prog->sh.LinkedTransformFeedback,
|
|
|
|
num_buffers, num_buffers, num_outputs,
|
|
|
|
num_buffers, num_buffers, num_outputs,
|
|
|
|
used_components, NULL, NULL,
|
|
|
|
used_components, NULL, NULL,
|
|
|
@@ -1645,7 +1651,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tfeedback_decls[i].is_next_buffer_separator()) {
|
|
|
|
if (tfeedback_decls[i].is_next_buffer_separator()) {
|
|
|
|
if (!tfeedback_decls[i].store(ctx, prog,
|
|
|
|
if (!tfeedback_decls[i].store(consts, prog,
|
|
|
|
xfb_prog->sh.LinkedTransformFeedback,
|
|
|
|
xfb_prog->sh.LinkedTransformFeedback,
|
|
|
|
buffer, num_buffers, num_outputs,
|
|
|
|
buffer, num_buffers, num_outputs,
|
|
|
|
used_components, explicit_stride,
|
|
|
|
used_components, explicit_stride,
|
|
|
@@ -1689,7 +1695,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!tfeedback_decls[i].store(ctx, prog,
|
|
|
|
if (!tfeedback_decls[i].store(consts, prog,
|
|
|
|
xfb_prog->sh.LinkedTransformFeedback,
|
|
|
|
xfb_prog->sh.LinkedTransformFeedback,
|
|
|
|
buffer, num_buffers, num_outputs,
|
|
|
|
buffer, num_buffers, num_outputs,
|
|
|
|
used_components, explicit_stride,
|
|
|
|
used_components, explicit_stride,
|
|
|
@@ -2762,7 +2768,8 @@ reserved_varying_slot(struct gl_linked_shader *stage,
|
|
|
|
* requirements of transform feedback.
|
|
|
|
* requirements of transform feedback.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
static bool
|
|
|
|
assign_varying_locations(struct gl_context *ctx,
|
|
|
|
assign_varying_locations(const struct gl_constants *consts,
|
|
|
|
|
|
|
|
const struct gl_extensions *exts,
|
|
|
|
void *mem_ctx,
|
|
|
|
void *mem_ctx,
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
gl_linked_shader *producer,
|
|
|
|
gl_linked_shader *producer,
|
|
|
@@ -2786,13 +2793,13 @@ assign_varying_locations(struct gl_context *ctx,
|
|
|
|
* packing required by transform feedback. See below for exception.
|
|
|
|
* packing required by transform feedback. See below for exception.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
bool xfb_enabled =
|
|
|
|
bool xfb_enabled =
|
|
|
|
ctx->Extensions.EXT_transform_feedback && !unpackable_tess;
|
|
|
|
exts->EXT_transform_feedback && !unpackable_tess;
|
|
|
|
|
|
|
|
|
|
|
|
/* Some drivers actually requires packing to be explicitly disabled
|
|
|
|
/* Some drivers actually requires packing to be explicitly disabled
|
|
|
|
* for varyings used by transform feedback.
|
|
|
|
* for varyings used by transform feedback.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
bool disable_xfb_packing =
|
|
|
|
bool disable_xfb_packing =
|
|
|
|
ctx->Const.DisableTransformFeedbackPacking;
|
|
|
|
consts->DisableTransformFeedbackPacking;
|
|
|
|
|
|
|
|
|
|
|
|
/* Disable packing on outward facing interfaces for SSO because in ES we
|
|
|
|
/* Disable packing on outward facing interfaces for SSO because in ES we
|
|
|
|
* need to retain the unpacked varying information for draw time
|
|
|
|
* need to retain the unpacked varying information for draw time
|
|
|
@@ -2804,17 +2811,17 @@ assign_varying_locations(struct gl_context *ctx,
|
|
|
|
* transform feedback and its not a SSO.
|
|
|
|
* transform feedback and its not a SSO.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
bool disable_varying_packing =
|
|
|
|
bool disable_varying_packing =
|
|
|
|
ctx->Const.DisableVaryingPacking || unpackable_tess;
|
|
|
|
consts->DisableVaryingPacking || unpackable_tess;
|
|
|
|
if (prog->SeparateShader && (producer == NULL || consumer == NULL))
|
|
|
|
if (prog->SeparateShader && (producer == NULL || consumer == NULL))
|
|
|
|
disable_varying_packing = true;
|
|
|
|
disable_varying_packing = true;
|
|
|
|
|
|
|
|
|
|
|
|
bool prefer_pot_aligned_varyings =
|
|
|
|
bool prefer_pot_aligned_varyings =
|
|
|
|
ctx->Const.PreferPOTAlignedVaryings;
|
|
|
|
consts->PreferPOTAlignedVaryings;
|
|
|
|
|
|
|
|
|
|
|
|
varying_matches matches(disable_varying_packing,
|
|
|
|
varying_matches matches(disable_varying_packing,
|
|
|
|
disable_xfb_packing,
|
|
|
|
disable_xfb_packing,
|
|
|
|
xfb_enabled,
|
|
|
|
xfb_enabled,
|
|
|
|
ctx->Extensions.ARB_enhanced_layouts,
|
|
|
|
exts->ARB_enhanced_layouts,
|
|
|
|
prefer_pot_aligned_varyings,
|
|
|
|
prefer_pot_aligned_varyings,
|
|
|
|
producer ? producer->Stage : MESA_SHADER_NONE,
|
|
|
|
producer ? producer->Stage : MESA_SHADER_NONE,
|
|
|
|
consumer ? consumer->Stage : MESA_SHADER_NONE);
|
|
|
|
consumer ? consumer->Stage : MESA_SHADER_NONE);
|
|
|
@@ -2968,7 +2975,7 @@ assign_varying_locations(struct gl_context *ctx,
|
|
|
|
(matched_candidate->toplevel_var->data.explicit_location &&
|
|
|
|
(matched_candidate->toplevel_var->data.explicit_location &&
|
|
|
|
matched_candidate->toplevel_var->data.location < VARYING_SLOT_VAR0 &&
|
|
|
|
matched_candidate->toplevel_var->data.location < VARYING_SLOT_VAR0 &&
|
|
|
|
(!consumer || consumer->Stage == MESA_SHADER_FRAGMENT) &&
|
|
|
|
(!consumer || consumer->Stage == MESA_SHADER_FRAGMENT) &&
|
|
|
|
(ctx->Const.ShaderCompilerOptions[producer->Stage].LowerBuiltinVariablesXfb &
|
|
|
|
(consts->ShaderCompilerOptions[producer->Stage].LowerBuiltinVariablesXfb &
|
|
|
|
BITFIELD_BIT(matched_candidate->toplevel_var->data.location)));
|
|
|
|
BITFIELD_BIT(matched_candidate->toplevel_var->data.location)));
|
|
|
|
|
|
|
|
|
|
|
|
if (lowered) {
|
|
|
|
if (lowered) {
|
|
|
@@ -3033,7 +3040,7 @@ assign_varying_locations(struct gl_context *ctx,
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
|
|
|
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
|
|
|
if (tfeedback_decls[i].is_varying()) {
|
|
|
|
if (tfeedback_decls[i].is_varying()) {
|
|
|
|
if (!tfeedback_decls[i].assign_location(ctx, prog)) {
|
|
|
|
if (!tfeedback_decls[i].assign_location(consts, prog)) {
|
|
|
|
ralloc_free(hash_table_ctx);
|
|
|
|
ralloc_free(hash_table_ctx);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -3102,7 +3109,8 @@ assign_varying_locations(struct gl_context *ctx,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
static bool
|
|
|
|
check_against_output_limit(struct gl_context *ctx,
|
|
|
|
check_against_output_limit(const struct gl_constants *consts,
|
|
|
|
|
|
|
|
gl_api api,
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
gl_linked_shader *producer,
|
|
|
|
gl_linked_shader *producer,
|
|
|
|
unsigned num_explicit_locations)
|
|
|
|
unsigned num_explicit_locations)
|
|
|
@@ -3122,11 +3130,11 @@ check_against_output_limit(struct gl_context *ctx,
|
|
|
|
|
|
|
|
|
|
|
|
assert(producer->Stage != MESA_SHADER_FRAGMENT);
|
|
|
|
assert(producer->Stage != MESA_SHADER_FRAGMENT);
|
|
|
|
unsigned max_output_components =
|
|
|
|
unsigned max_output_components =
|
|
|
|
ctx->Const.Program[producer->Stage].MaxOutputComponents;
|
|
|
|
consts->Program[producer->Stage].MaxOutputComponents;
|
|
|
|
|
|
|
|
|
|
|
|
const unsigned output_components = output_vectors * 4;
|
|
|
|
const unsigned output_components = output_vectors * 4;
|
|
|
|
if (output_components > max_output_components) {
|
|
|
|
if (output_components > max_output_components) {
|
|
|
|
if (ctx->API == API_OPENGLES2 || prog->IsES)
|
|
|
|
if (api == API_OPENGLES2 || prog->IsES)
|
|
|
|
linker_error(prog, "%s shader uses too many output vectors "
|
|
|
|
linker_error(prog, "%s shader uses too many output vectors "
|
|
|
|
"(%u > %u)\n",
|
|
|
|
"(%u > %u)\n",
|
|
|
|
_mesa_shader_stage_to_string(producer->Stage),
|
|
|
|
_mesa_shader_stage_to_string(producer->Stage),
|
|
|
@@ -3146,7 +3154,8 @@ check_against_output_limit(struct gl_context *ctx,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
static bool
|
|
|
|
check_against_input_limit(struct gl_context *ctx,
|
|
|
|
check_against_input_limit(const struct gl_constants *consts,
|
|
|
|
|
|
|
|
gl_api api,
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
struct gl_shader_program *prog,
|
|
|
|
gl_linked_shader *consumer,
|
|
|
|
gl_linked_shader *consumer,
|
|
|
|
unsigned num_explicit_locations)
|
|
|
|
unsigned num_explicit_locations)
|
|
|
@@ -3166,11 +3175,11 @@ check_against_input_limit(struct gl_context *ctx,
|
|
|
|
|
|
|
|
|
|
|
|
assert(consumer->Stage != MESA_SHADER_VERTEX);
|
|
|
|
assert(consumer->Stage != MESA_SHADER_VERTEX);
|
|
|
|
unsigned max_input_components =
|
|
|
|
unsigned max_input_components =
|
|
|
|
ctx->Const.Program[consumer->Stage].MaxInputComponents;
|
|
|
|
consts->Program[consumer->Stage].MaxInputComponents;
|
|
|
|
|
|
|
|
|
|
|
|
const unsigned input_components = input_vectors * 4;
|
|
|
|
const unsigned input_components = input_vectors * 4;
|
|
|
|
if (input_components > max_input_components) {
|
|
|
|
if (input_components > max_input_components) {
|
|
|
|
if (ctx->API == API_OPENGLES2 || prog->IsES)
|
|
|
|
if (api == API_OPENGLES2 || prog->IsES)
|
|
|
|
linker_error(prog, "%s shader uses too many input vectors "
|
|
|
|
linker_error(prog, "%s shader uses too many input vectors "
|
|
|
|
"(%u > %u)\n",
|
|
|
|
"(%u > %u)\n",
|
|
|
|
_mesa_shader_stage_to_string(consumer->Stage),
|
|
|
|
_mesa_shader_stage_to_string(consumer->Stage),
|
|
|
@@ -3239,7 +3248,9 @@ link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
|
|
|
|
|
|
|
|
|
|
|
|
tfeedback_decls = rzalloc_array(mem_ctx, tfeedback_decl,
|
|
|
|
tfeedback_decls = rzalloc_array(mem_ctx, tfeedback_decl,
|
|
|
|
num_tfeedback_decls);
|
|
|
|
num_tfeedback_decls);
|
|
|
|
if (!parse_tfeedback_decls(ctx, prog, mem_ctx, num_tfeedback_decls,
|
|
|
|
if (!parse_tfeedback_decls(&ctx->Const,
|
|
|
|
|
|
|
|
&ctx->Extensions,
|
|
|
|
|
|
|
|
prog, mem_ctx, num_tfeedback_decls,
|
|
|
|
varying_names, tfeedback_decls))
|
|
|
|
varying_names, tfeedback_decls))
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -3254,7 +3265,8 @@ link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
|
|
|
|
(num_tfeedback_decls != 0 || prog->SeparateShader)) {
|
|
|
|
(num_tfeedback_decls != 0 || prog->SeparateShader)) {
|
|
|
|
const uint64_t reserved_out_slots =
|
|
|
|
const uint64_t reserved_out_slots =
|
|
|
|
reserved_varying_slot(prog->_LinkedShaders[last], ir_var_shader_out);
|
|
|
|
reserved_varying_slot(prog->_LinkedShaders[last], ir_var_shader_out);
|
|
|
|
if (!assign_varying_locations(ctx, mem_ctx, prog,
|
|
|
|
if (!assign_varying_locations(&ctx->Const,
|
|
|
|
|
|
|
|
&ctx->Extensions, mem_ctx, prog,
|
|
|
|
prog->_LinkedShaders[last], NULL,
|
|
|
|
prog->_LinkedShaders[last], NULL,
|
|
|
|
num_tfeedback_decls, tfeedback_decls,
|
|
|
|
num_tfeedback_decls, tfeedback_decls,
|
|
|
|
reserved_out_slots))
|
|
|
|
reserved_out_slots))
|
|
|
@@ -3274,8 +3286,8 @@ link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
|
|
|
|
if (first == last) {
|
|
|
|
if (first == last) {
|
|
|
|
gl_linked_shader *const sh = prog->_LinkedShaders[last];
|
|
|
|
gl_linked_shader *const sh = prog->_LinkedShaders[last];
|
|
|
|
|
|
|
|
|
|
|
|
do_dead_builtin_varyings(ctx, NULL, sh, 0, NULL);
|
|
|
|
do_dead_builtin_varyings(&ctx->Const, ctx->API, NULL, sh, 0, NULL);
|
|
|
|
do_dead_builtin_varyings(ctx, sh, NULL, num_tfeedback_decls,
|
|
|
|
do_dead_builtin_varyings(&ctx->Const, ctx->API, sh, NULL, num_tfeedback_decls,
|
|
|
|
tfeedback_decls);
|
|
|
|
tfeedback_decls);
|
|
|
|
|
|
|
|
|
|
|
|
if (prog->SeparateShader) {
|
|
|
|
if (prog->SeparateShader) {
|
|
|
@@ -3285,7 +3297,8 @@ link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
|
|
|
|
/* Assign input locations for SSO, output locations are already
|
|
|
|
/* Assign input locations for SSO, output locations are already
|
|
|
|
* assigned.
|
|
|
|
* assigned.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (!assign_varying_locations(ctx, mem_ctx, prog,
|
|
|
|
if (!assign_varying_locations(&ctx->Const,
|
|
|
|
|
|
|
|
&ctx->Extensions, mem_ctx, prog,
|
|
|
|
NULL /* producer */,
|
|
|
|
NULL /* producer */,
|
|
|
|
sh /* consumer */,
|
|
|
|
sh /* consumer */,
|
|
|
|
0 /* num_tfeedback_decls */,
|
|
|
|
0 /* num_tfeedback_decls */,
|
|
|
@@ -3312,11 +3325,12 @@ link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
|
|
|
|
const uint64_t reserved_in_slots =
|
|
|
|
const uint64_t reserved_in_slots =
|
|
|
|
reserved_varying_slot(sh_next, ir_var_shader_in);
|
|
|
|
reserved_varying_slot(sh_next, ir_var_shader_in);
|
|
|
|
|
|
|
|
|
|
|
|
do_dead_builtin_varyings(ctx, sh_i, sh_next,
|
|
|
|
do_dead_builtin_varyings(&ctx->Const, ctx->API, sh_i, sh_next,
|
|
|
|
next == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
|
|
|
|
next == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
|
|
|
|
tfeedback_decls);
|
|
|
|
tfeedback_decls);
|
|
|
|
|
|
|
|
|
|
|
|
if (!assign_varying_locations(ctx, mem_ctx, prog, sh_i, sh_next,
|
|
|
|
if (!assign_varying_locations(&ctx->Const, &ctx->Extensions,
|
|
|
|
|
|
|
|
mem_ctx, prog, sh_i, sh_next,
|
|
|
|
next == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
|
|
|
|
next == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
|
|
|
|
tfeedback_decls,
|
|
|
|
tfeedback_decls,
|
|
|
|
reserved_out_slots | reserved_in_slots))
|
|
|
|
reserved_out_slots | reserved_in_slots))
|
|
|
@@ -3325,13 +3339,13 @@ link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
|
|
|
|
/* This must be done after all dead varyings are eliminated. */
|
|
|
|
/* This must be done after all dead varyings are eliminated. */
|
|
|
|
if (sh_i != NULL) {
|
|
|
|
if (sh_i != NULL) {
|
|
|
|
unsigned slots_used = util_bitcount64(reserved_out_slots);
|
|
|
|
unsigned slots_used = util_bitcount64(reserved_out_slots);
|
|
|
|
if (!check_against_output_limit(ctx, prog, sh_i, slots_used)) {
|
|
|
|
if (!check_against_output_limit(&ctx->Const, ctx->API, prog, sh_i, slots_used)) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned slots_used = util_bitcount64(reserved_in_slots);
|
|
|
|
unsigned slots_used = util_bitcount64(reserved_in_slots);
|
|
|
|
if (!check_against_input_limit(ctx, prog, sh_next, slots_used))
|
|
|
|
if (!check_against_input_limit(&ctx->Const, ctx->API, prog, sh_next, slots_used))
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
next = i;
|
|
|
|
next = i;
|
|
|
@@ -3339,7 +3353,8 @@ link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!store_tfeedback_info(ctx, prog, num_tfeedback_decls, tfeedback_decls,
|
|
|
|
if (!store_tfeedback_info(&ctx->Const, prog,
|
|
|
|
|
|
|
|
num_tfeedback_decls, tfeedback_decls,
|
|
|
|
has_xfb_qualifiers, mem_ctx))
|
|
|
|
has_xfb_qualifiers, mem_ctx))
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|